by community-syndication | Jan 9, 2010 | BizTalk Community Blogs via Syndication
Ever wondered if your BizTalk is all it can be?
Verifying your BizTalk Server installation is not an easy thing to do. So far the BizTalk Server 2009 Performance Optimization Guide is probably your safest bet. The Optimization Guide provides in-depth information for optimizing the performance of a BizTalk Server solution. However, it won’t help you evaluate you BizTalk installation at runtime. To do this, you’ll have to continue analyzing it using Performance Analysis of Logs (PAL).
I’m not saying these aren’t good tools. In fact they are great. They are however quite extensive, and will ultimately not answer the question: “Do I get the expected workload through BizTalk?”.
Ewan Fairweather, together with some other smart people at Microsoft, have put together a comprehensive study about scaling out BizTalk. The principal is simple, test the same scenarios with different environments and quantify the scale out capabilities of one to four BizTalk servers and one to three message boxes.
The BizTalk Server 2009 Scale Out Testing Study provides sizing and scaling guidance for BizTalk Server. However, you’d find it challenging to compare your environment to these numbers as you haven’t got access to the same testing scenarios. And even if you did, you still couldn’t be sure you’ve configured it the same, and that you have been running the equivalent LoadGen scripts.
Four months ago, I contacted Ewan to ask him if he had some testing scenario I could run to evaluate the environment I was currently working on. He didn’t, but seemed very aware of the lack of such a “tool”. One thing led to another and we came to the conclusion we should make it ourselves.
– Today, four months later, we are happy to announce that BizTalk Benchmark Wizard is publicly available on Codeplex.
The goal has been to make an easy to install and simple to use, wizard-like application with which one could test a BizTalk environment- and compare the result to the study. One of the challenges where to scope the project, and prevent ourselves from solving problems already addressed in tools such as LoadGen and PAL. For instance, BizTalk Benchmark Wizard is NOT
a load tool
Although it does create load, it only does so against ONE receive host. The application could work against multiple receive hosts, in fact the earlier versions did, but it required a much more complex setup process from the user. We came to the conclusion that if your environment measures up using only one receive host, it most likely would do so using multiple hosts.
By setting these limitations, it also simplifies the comparison of environments and benchmarking them against the result from the Microsoft Study.
an analyzing tool
The tool does not analyze any eventual problems or bottlenecks. Neither does it give any hints or advice of how to solve them. It does however collect Perfmon counter data from each of the servers, both BizTalk and SQL. If your environment fails the test, you can analyze the data using the PAL tool.
How it works:
- After the user has started the application and specified the BizTalk Group, the tool analyzes its configuration, finding all the BizTalk servers, Messageboxes etc.
- Secondly, the user gets to select one of two scenarios: Messaging or Orchestration. Each scenario has a set of tested environments such as
- “Single server (2*Quad CPU, 4GB RAM)”
- “1*BTS (1*Quad CPU. 4GB RAM) + 1*SQL(1*Quad CPU, 8GB RAM)”.
- “2*BTS (2*Quad CPU. 8GB RAM) + 2*SQL(2*Quad CPU, 16GB RAM)”.
- The user selects the environment which most resembles his/her own.
- The user then starts the Indigo Service, a console application hosting a service which will be called from the BizTalk Send port.
- As the user clicks “Run test”, the tool continues to start ports and orchestrations. It will also start the Perfmon collector sets if the user has chosen to create those.
- As the test proceeds the user can monitor the counter values through the gauges (CPU utilization, Received msgs/sec and Processed msgs/sec). The default test duration is 30 minutes, with a warm-up of 2 minutes.
- Finally, the user is presented a result, which is either Succeeded or Failed.
If you pass the test, you can proudly submit your result to the the High Score list. “E.W.N” seams to be the one to beat
by community-syndication | Jan 8, 2010 | BizTalk Community Blogs via Syndication
I recently got the pleasure of the Richard Seroter 4 questions treatment….. (not as bad as it sounds) 🙂
Anyway if anyone is remotely interested in what I have to say then please check out the post
http://seroter.wordpress.com/2010/01/03/interview-series-four-questions-with-michael-stephenson/
by community-syndication | Jan 8, 2010 | BizTalk Community Blogs via Syndication
For a while ive hada bunch of resources of my own and some links to other community resources which are very useful for BizTalk testing.
Ive pulled these all together into one chm file which can point you to all of the appropriate resources to make life easier.
This is available on the below link:
http://code.msdn.microsoft.com/BTSTestGuide
If anyone feels ive missed a good resource please let me know and ill update it.
by community-syndication | Jan 8, 2010 | BizTalk Community Blogs via Syndication
I just added a new webcast “Introduction to WCF Workflow Services” to CloudCasts. I’ve been playting around with WCF and WF in .NET 4.0 and AppFabric for a while now, and will get into the habit of releasing webcasts every week or so. (Well that’s the new year’s resolution anyway)
The webcast is here.
by community-syndication | Jan 8, 2010 | BizTalk Community Blogs via Syndication
A few months ago my colleague Don Demsak and I started collaborating on a paper about the principles of “Lightweight SOAs”. Fundamentally, the paper intends to demystify some of the aspects around big SOA enterprise projects and propose some patterns…(read more)
by community-syndication | Jan 7, 2010 | BizTalk Community Blogs via Syndication
This is part one of a twelve part series that introduces the features of WCF WebHttp Services in .NET 4. In this post we will cover:
- Downloading and using the new online project templates for WCF WebHttp Services
- Learning the basics of a WCF WebHttp Service: [WebGet] and UriTemplates
- Creating a simple web service that honors HTTP GET requests to developer-defined URIs
The TeamTask Web Service
Over the course of this blog post series, we will be building a web service called TeamTask that utilizes all of the new features available in WCF WebHttp Services. The TeamTask service allows a team to track tasks that are assigned to members of the team. It is a relatively simple service that introduces the concept of a user and the concept of a task. A user has a name, a manager, and a list of assigned tasks. A task has an id, a title, a status (in progress, blocked, completed, etc.), relevant dates and an owner.
For our TeamTask service, we will be using an ADO.NET Entity Data Model(EDM) to model these concepts of a user and a task. Here is a graphical view of the data model for the TeamTask service:
Downloading the TeamTask Code
At the end of this blog post, you’ll find a link that will allow you to download the code for the current TeamTask Service as a compressed file. After extracting, you’ll find that it contains “Before” and “After” versions of the TeamTask solution. If you would like to follow along with the steps outlined in this post, download the code and open the “Before” solution in Visual Studio 2010. If you aren’t sure about a step, refer to the “After” version of the TeamTask solution.
Note: If you try running the sample code and see a Visual Studio Project Sample Loading Error that begins with “Assembly could not be loaded and will be ignored”, see here for troubleshooting.
Getting Visual Studio 2010
To follow along with this blog post series, you will need to have Microsoft Visual Studio 2010 and the full .NET 4 Framework installed on your machine. (The client profile of the .NET 4 Framework is not sufficient.) At the time of this posting, the Microsoft Visual Studio 2010 Ultimate Beta 2 is available for free download and there are numerous resources available regarding how to download and install, including this Channel 9 video.
Step 1: Downloading the New Online Project Templates
You won’t find any project templates for WCF WebHttp Services out-of-the-box with Visual Studio 2010. However, using a new feature in Visual Studio 2010 called the Extension Manager, locating and downloading our new online templates is quick and easy.
- In Visual Studio 2010, open the Extension Manager from the main menu bar using “Tools”->”Extension Manager”.
On the left-hand side of the Extension Manager, select the “Online Gallery” and then select “Templates”->”WCF” from the tree-view control that appears. This will list the relevant templates that are available online. At the time of this writing, the following templates were available:
Click on the “Download” button for the WCF REST Service Template 40(CS) and follow the prompts. Of course, if you are more comfortable with Visual Basic than C#, there is also a VB template. (Although this blog post series will be entirely in C#.) Note: There are also templates for .NET 3.5, but using these templates will preclude the use of the new .NET 4 features that are the focus of this blog post series.
Step 2: Creating the TeamTask.Service Project
With the online template installed, you can now easily create a new WCF WebHttp Service.
If you haven’t already done so, download and open the “Before” solution of the code attached to this blog post. You’ll find that the solution doesn’t have a project but includes a number of loose files within two solution folders: Database and Model. We’ll move these into our new project after we create it.
In the “Solution Explorer” window (Ctrl + W, S), right click on the TeamTask solution and select “Add”->”New Project”. This will open the “New Project” dialog window.
On the left-hand side of the “New Project” dialog window select “Installed Templates” and then select “Visual C#”->”Web” from the tree-view control. Choose the “WCF REST Service Application” project template. Note: If you do not see the installed “WCF REST Service Application” project template, you might need to enable the loading of per-user extensions. There will be a link below the template selection area if this is the case. Follow this link to enable the loading of per-user extensions. You may need to restart Visual Studio.
For the project name enter “TeamTask.Service” and then click “Ok”. This will create the TeamTask.Service project in the solution.
Step 3: Exploring the Online Template Project
Before we start implementing our service, we should briefly look at the items that were created in the TeamTask.Service project with the online template. If you’re unsure about the code in these files, don’t worry. We’ll explain the reason behind every custom attribute and configuration setting over the course of building the TeamTask service.
Service1.cs: This code file provides an empty implementation of a WCF WebHttp Service class. The Service1 class includes web operations, which are methods decorated with [WebGet] and [WebInvoke] attributes to indicate the HTTP method and URIs that map to the method.
SampleItem.cs: This code file provides a default data type that is used by the Service1 class. The SampleItem class is deserialized/serialized as the body of request/response HTTP messages.
Web.config: This is a standard .NET configuration file created for web projects, although this one doesn’t have a lot of markup. One of the new features in WCF WebHttp Services is the simplified configuration.
Global.asax: This is an ASP.NET application file that can be used in WCF WebHttp Services for registering simple ASP.NET Routes for your service(s). Routing is a useful way of composing smaller, more manageable WCF WebHttp Services into a larger web application. We’ll look at routes in more detail in part six of this blog series.
Helpful Tip: If you’ve used WCF 3.5 or the WCF REST Starter Kit to build non-SOAP HTTP services in the past, you may recall that hosting in IIS required a .svc file. You may also notice that the online template for WCF WebHttp Services in .NET 4 doesn’t generate a .svc file. This is because ASP.NET routing can now be used instead of .svc files when hosting in IIS. Routes are generally preferable because they give you more control over your URIs. |
Step 4: Adding the Database and Entity Framework Items
The loose files within the “Before” solution attached to this blog post were created to save you the effort of having to create them yourself. None of these items are essential to a WCF WebHttp Service so we didn’t want to cover their creation in depth, but we’ll be using them for our TeamTask web service. Within the “Database” solution folder is an in-project database that has already been created for the TeamTask service. Within the “Model” solution folder is an ADO.NET Entity Data Model (EDM) (TeamTask.edmx) and related classes.
If you are unfamiliar with the ADO.NET Entity Framework, it provides object/relational mapping to easily move data between a database and in-memory CLR instances. The types that the ADO.NET Entity Framework populate with data from the backing data store are referred to as entity types. For the TeamTask service, we have the Task and User entity types in the “Model” solution folder.
Actually the Task and User types are POCO entity types. POCO entities types are a new feature in the ADO.NET Entity Framework for .NET 4. With POCO entity types, a developer has complete control over the type definition and the attributes that are applied to the type and its members. Later, we’ll see that this is important because it allows us to control the content of our HTTP responses. You can see here for details about POCO entity types and how they can be created, but all you need to understand is that the POCO entity types “work” because they have properties with the same names as those used in the EDM (TeamTask.edmx).
The “Model” solution folder also contains a hand-coded TeamTaskObjectContext class (TeamTaskObjectContext.cs) that derives from the ObjectContext base class in the Entity Framework. The TeamTaskObjectContext is the primary means by which we’ll interact with the database as it exposes collections of the User and Task POCO entity types.
In the “Solution Explorer” window (Ctrl + W, S), right click on the TeamTask.Service project and select “Add”->”New Folder”. Name the new folder “Model”.
Copy all of the files from the “Model” solution folder into the “Model” folder of the TeamTask.Service.
Copy the TeamTask.mdf and TeamTask_log.ldf files from the “Database” solution folder into the “App_Data” folder of the TeamTask.Service.
In order for the TeamTask code to get task and user data from the database, we need to add a database connection string to the Web.config file of the TeamTask.Service project. Open the App.Config file in the “Database” solution folder and copy the full <connectionStrings> element into the <configuration> element of the Web.config.
We no longer need the loose files, so right click on the “Solution Items” folder in the “Solution Explorer” window and select “Remove” from the context menu.
Because we want to use our POCO entity types, we need to disable the default entity generation that the ADO.NET Entity Framework provides. In the “Solution Explorer” window (Ctrl + W, S), right click on the TeamTask.edmx file and select “Properties” from the context menu. In the “Properties” window, you’ll find that the “Custom Tool” entry has a value of “EntityModelCodeGenerator”. Clear this value and leave it blank as shown below. This will disable the default entity generation.
Step 5: Setting the Base Address of our Service
When creating a new web project in Visual Studio the project will be configured by default to use a randomly assigned port with the development server. To reduce confusion and allow you to copy and paste URIs from these blog posts without editing the port, we’ll configure the debug development server to use a specific port.
We’ll also configure the virtual path for the TeamTask service and set the route path for our service to an empty string. The route path is part of the new routes feature introduced with WCF WebHttp Services in .NET 4. We’ll discuss routes in more detail in part six of this blog post series. For now, the important thing to understand is that the base address of the TeamTask service is constructed from the host name and port, the virtual path and the route path (which will effectively be nothing as an empty string).
In the “Solution Explorer” window, right click on the TeamTask.Service project and select “Properties” from the context menu.
In the TeamTask.Service properties editor, select the “Web” tab.
Under the “Servers” section, click on the “Specific Port” radio button and enter “8080” as the port number. Also set the virtual path to “/TeamTask”.
Open the Global.asax file in the code editor.
In the RegisterRoutes() method, replace the route path “Service1” with an empty string like so:
RouteTable.Routes.Add(new ServiceRoute(“”, new WebServiceHostFactory(),
typeof(Service1)));
Now when we run the TeamTask service from within Visual Studio, all of the service operations will be exposed at URIs relative to the base address:
http://localhost:8080/TeamTask/
Step 6: Getting a List of Tasks from the TeamTaskService
We’re now ready to create the TeamTaskService. We’ll implement a simple service operation that returns all of the tasks from the database.
Rename the Service1.cs file to “TeamTaskService.cs” by right-clicking on it in the “Solution Explorer” window and selecting “Rename” from the context menu. A dialog box should appear asking if you want to rename all references in the project to the code element “Service1”. Select “Yes”.
Open the newly renamed TeamTaskService.cs file in the code editor.
Since we only want a single service operation for now, delete all of the operations in the TeamTaskService class except for the GetCollection() operation, which you should rename to GetTasks().
Change the UriTemplate value on the GetTasks() operation from an empty string to “Tasks”. This specifies that an HTTP GET request with a URI of “http://localhost:8080/TeamTask/Tasks” will be handled by the GetTasks() operation. This is a simple UriTemplate that specifies just a single URI, but as we’ll see later, UriTemplates can be much more expressive and can represent entire sets of URIs.
Change the return type of the GetTasks() operation to List<Task>. In order to do this, you’ll need to add “using TeamTask.Model;” to the code file.
Implement the GetTasks() operation such that it uses the TeamTaskObjectContext to get all of the tasks from the database. The TeamTaskObjectContext is the ADO.NET ObjectContext that we hand-coded to work with our POCO entity types. It allows us to query the database for the tasks using LINQ:
[WebGet(UriTemplate = “Tasks”)]
public List<Task> GetTasks()
{
using (TeamTaskObjectContext objectContext =
new TeamTaskObjectContext())
{
return objectContext.Tasks.OrderBy(task => task.Id).ToList();
}
}
Start without debugging (Ctrl+F5) and use the browser of your choice to navigate to http://localhost:8080/TeamTask/Tasks. In Internet Explorer, the list of tasks will be displayed as shown below:
Helpful Tip: If you’ve used WCF 3.5 or the WCF REST Starter Kit to build non-SOAP HTTP services in the past, you may recall that operations required both a [WebGet] or [WebInvoke] attribute and an [OperationContract] attribute. You may also notice that we are not using [OperationContract] attributes on the GetTasks() operation. This is because in WCF WebHttp Service for .NET 4, the [OperationContract] attribute is now optional. |
Step 7: Getting a User and His or Her Tasks
Now that we have an operation for retrieving a list of tasks from our TeamTask service, let’s create a second operation for retrieving users. With this new operation we’ll use a UriTemplate that contains a variable so that individual users can be retrieved by supplying a username in the URI.
Open the TeamTaskService.cs file in the code editor if it isn’t already open.
Add a public method called GetUser() that takes a username parameter of type string and returns a User type like so:
public User GetUser(string userName)
To make the GetUser() method an explicit service operation, add a [WebGet] attribute with a UriTemplate value of “Users/{userName}” like so:
[WebGet(UriTemplate = “Users/{userName}”)]
public User GetUser(string userName)
Notice that the UriTemplate has the name “userName” surrounded by curly braces. These curly braces indicate that “userName” is a variable and not a literal like the “Users” portion of the UriTemplate. The presence of this “userName” variable means that this UriTemplate specifies a set of URIs instead of just a single URI. In this case, the UriTemplate specifies URIs that have a path of “Users/” followed by one additional path segment. For example, URIs (relative to the service base address) such as “Users/annc” or “Users/maryt” would match this UriTemplate, but URIs such as “Users/”, “Tasks/annc”, or “Users/maryt/reports” would not.
Also notice that the GetUser() method has a parameter with the name “userName”. It is not a coincidence that the UriTemplate variable and the method parameter share the same name. By using the same name, the WCF WebHttp Services infrastructure knows to map the UriTemplate variable value from the URI of the request to the method parameter when the operation is invoked. For example, if the request URI were “Users/annc”, the GetUser() method would be invoked with the value of “annc”.
Implement the GetUser() operation using the TeamTaskObjectContext, similar to what was done for the GetTasks() operation:
using (TeamTaskObjectContext objectContext =
new TeamTaskObjectContext())
{
// The ‘Include’ method is an ADO.NET Entity Framework feature that
// allows us to load the user and his/her tasks in a single query!
var user = objectContext.Users.Include(“Tasks”)
.FirstOrDefault(u => u.UserName == userName);
return user;
}
Start without debugging and navigate to http://localhost:8080/TeamTask/Users/user1. In Internet Explorer, the list of tasks will be displayed as shown below:
Helpful Tip: For more details about how UriTemplates work, see here. |
Step 8: Filtering the List of Tasks with Query String Parameters
With a limited number of tasks in the database, having the TeamTask service return every task with each request isn’t a problem. But of course, for a real world web service with lots of tasks this would be impractical. We need a way to filter the list of tasks on the server, and we can do this by adding query string parameters to the UriTemplate on the GetTasks() operation.
We’ll add “skip” and “top” query string parameters to provide a paging mechanism; given an ordered list of tasks, the “skip” parameter will indicate not to return the first N tasks in the list and the “top” parameter will indicate the maximum number of tasks to return.
We’ll also add an “owner” query string parameter via which a username can be supplied. When the “owner” is specified, only tasks for the given user will be included in the list of tasks returned.
Open the TeamTaskService.cs file in the code editor if it isn’t already open.
The UriTemplate value for the GetTasks() operation is already “Tasks”. Add the query string parameters “skip”, “top” and “owner” along with UriTemplate variables. Also add parameters to the method with names that match the UriTemplate variables like so:
[WebGet(UriTemplate = “Tasks?skip={skip}&top={top}&owner={userName}”)]
public List<Task> GetTasks(int skip, int top, string userName)
Notice that the skip and top method parameters are of type int and not simply strings. With query string variables, the WCF WebHttp Services infrastructure can provide conversion from the string value to other common types.
Query string parameters are not required, so it is possible that our GetTasks() operation will handle request URIs that don’t include “skip”, “top” or “owner” query string values. Add some code to make sure we use reasonable “skip” and “top” values like so:
// Set reasonable defaults for the query string parameters
skip = (skip >= 0) ? skip : 0;
top = (top > 0) ? top : 25;
Note: If a query string value isn’t present in the request URI, the method parameter will be the default value of its given type.
We also need to check for a null userName value, but this can be done while building the query, because we only want to include a LINQ Where clause if there is a userName value:
// Include the where clause only if a userName was provided
IQueryable<Task> taskQuery = (string.IsNullOrWhiteSpace(userName)) ?
objectContext.Tasks.AsQueryable<Task>() :
objectContext.Tasks.Where(task => task.OwnerUserName == userName);
Lastly, add the LINQ Skip and Take clauses to the query so that the final implementation of the GetTasks() operation looks like:
[WebGet(UriTemplate = “Tasks?skip={skip}&top={top}&owner={userName}”)]
public List<Task> GetTasks(int skip, int top, string userName)
{
// Set reasonable defaults for the query string parameters
skip = (skip >= 0) ? skip : 0;
top = (top > 0) ? top : 25;
using (TeamTaskObjectContext objectContext =
new TeamTaskObjectContext())
{
// Include the where clause only if a userName was provided
var taskQuery = (string.IsNullOrWhiteSpace(userName)) ?
objectContext.Tasks :
objectContext.Tasks.Where(
task => task.OwnerUserName == userName);
return taskQuery.OrderBy(task => task.Id)
.Skip(skip).Take(top).ToList();
}
}
Start without debugging and navigate to: http://localhost:8080/TeamTask/Tasks?skip=1&top=2. The list of tasks will be filtered to only include tasks 2 & 3 as shown below:
Notice that the “owner” query string parameter wasn’t provided, so the tasks were not filtered by userName.
Next Steps: Clients and the Automatic Help Page in WCF WebHttp Services
We’ve got our TeamTask service up and running, and we can use the browser to retrieve tasks and users. But web services are all about programmatic access, so in the part two of this series we’ll create a client to consume our TeamTask service. We’ll also look at the automatic help page feature in WCF WebHttp Services that makes it easier to build such clients.
Randall Tombaugh
Developer, WCF WebHttp Services
by community-syndication | Jan 6, 2010 | BizTalk Community Blogs via Syndication
Over the next six weeks we are going to be releasing a series of blog posts that will focus on the new features in .NET 4 around WCF WebHttp Services.
WCF WebHttp Services is the flavor of WCF that is most appropriate for developers who need complete control over the URI, format, and protocol when building non-SOAP HTTP services-services that may or may not subscribe to RESTful architectural constraints. For the other technologies in the WCF services eco-system and the developer scenarios they best support, see here.
For those of you who have used WCF 3.5 or the WCF REST Starter Kit to build non-SOAP services, you’ll find that WCF WebHttp Services is the vehicle that brings these technologies forward to .NET 4. You’ll find the familiar programming model that uses [WebGet] and [WebInvoke] attributes to map an HTTP request to a WCF operation. But you’ll also find a number of new features in WCF WebHttp Services that make it even easier to build operation-centric or RESTful web services over HTTP.
For those of you who are new to WCF or who have only used WCF for building SOAP-based services in the past, you’ll find that this series of blog posts will bring you up to speed quickly on everything you need to know to start building non-SOAP HTTP services in which you have complete control over the URI, format and protocol.
To give you a sense of the features we will be covering in this series on WCF WebHttp Services in .NET 4, here is an index of the upcoming blog posts (we’ll update these links as the posts go public):
- Getting Started with WCF WebHttp Services in .NET 4
- Clients and the Automatic Help Page in WCF WebHttp Services
- Updating State in WCF WebHttp Services
- Automatic and Explicit Format Selection in WCF WebHttp Services
- Error Handling in WCF WebHttp Services with WebFaultException
- Using Routes to Compose WCF WebHttp Services
- Integrating ASP.NET Output Caching with WCF WebHttp Services
- Returning Custom Formats from WCF WebHttp Services
- Creating Views in WCF WebHttp Services with T4
- Conditional GET and Etag Support in WCF WebHttp Services
- Optimistic Concurrency Support in WCF WebHttp Services
- Guidance on Link Generation in WCF WebHttp Services
We’re really excited about the new features introduced with WCF WebHttp Services in .NET 4 and we look forward to hearing your feedback in the comments to the blog posts. Hope you find the upcoming blog post series both interesting and informative.
Randall Tombaugh
Developer, WCF WebHttp Services
by community-syndication | Jan 6, 2010 | BizTalk Community Blogs via Syndication
When using the new System.DirectoryServices.AccountManagement namespace, one might be inclined (as was I) to use the following code to add a user to a group (exception and comments handling removed):
using (GroupPrincipal groupPrincipal =
GroupPrincipal.FindByIdentity(
domainContext,
System.DirectoryServices.AccountManagement.IdentityType.Name,
groupName))
{
if (groupPrincipal != null)
{
using (UserPrincipal userPrincipal =
UserPrincipal.FindByIdentity(
domainContext,
System.DirectoryServices.AccountManagement.IdentityType.UserPrincipalName,
UPN))
{
if (userPrincipal != null)
{
groupPrincipal.GroupScope = GroupScope.Global;
groupPrincipal.Members.Add(userPrincipal);
groupPrincipal.Save();
}
}
}
}
This works just fine if your machine is joined to the domain you’re trying to provision. However, if your machine is not joined, the groupPrincipal.Save(); call throws a PrincipalException with an error code 1355 (“Information about the domain could not be retrieved (1355)”).
Joining the domain solves this issue.
So what if joining the domain isn’t an option?
In this case I found resorting to good old System.DirectoryServices fixes the issue, using the following code fragment:
using (UserPrincipal userPrincipal =
UserPrincipal.FindByIdentity(domainContext, UPN))
{
if (userPrincipal != null)
{
using (GroupPrincipal groupPrincipal =
GroupPrincipal.FindByIdentity(domainContext, groupName))
{
if (groupPrincipal != null)
{
if (!userPrincipal.IsMemberOf(groupPrincipal))
{
string userSid = string.Format("<SID={0}>",
((DirectoryEntry)userPrincipal.GetUnderlyingObject()).ToSidString());
DirectoryEntry groupDirectoryEntry =
(DirectoryEntry)groupPrincipal.GetUnderlyingObject();
groupDirectoryEntry.Properties["member"].Add(userSid);
groupDirectoryEntry.CommitChanges();
}
}
}
}
}
ToSidString is an extension method which translates the “objectSid” property:
public static string ToSidString(this DirectoryEntry entry)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in (byte[])entry.Properties["objectSid"].Value)
{
sb.Append(b.ToString("X2"));
}
return sb.ToString();
}
HTH!
by community-syndication | Jan 6, 2010 | BizTalk Community Blogs via Syndication
Recently, I used Unity v1.2, which in my opinion is a great product. I had difficulty, however, with the configuration for a scenario I encountered. I needed an enum value to be passed to a constructor. Trying as I might, there was no way Unity was accepting my typeAlias, as such:
<unity>
<typeAliases>
<typeAlias
alias="contextType"
type="System.DirectoryServices.AccountManagement.ContextType,
System.DirectoryServices.AccountManagement, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</typeAliases>
<containers>
<container name="identitystores">
<types>
<type name="primary" type="IIdentityStore" mapTo="ActiveDirectoryIdentityStore" >
<lifetime type="singleton" />
<typeConfig
extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="context" parameterType="contextType">
<value
value="Domain"
type="contextType" />
</param>
</constructor>
</typeConfig>
</type>
</types>
</container>
</containers>
</unity>
For the life of me, I couldn’t figure out what I did wrong. I asked in an internal discussion list, and someone mentioned writing a plain old TypeConverter… Right he was, getting my enum value to work was pretty easy. The TypeConverter (as always, comments removed for clarity and provided AS IS, etc.):
public class ContextTypeTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType.GetType() == typeof(string);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(ContextType);
}
public override object ConvertFrom(
ITypeDescriptorContext context,
CultureInfo culture,
object value)
{
return Enum.Parse(typeof(ContextType), (string)value);
}
public override object ConvertTo(
ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destinationType)
{
return Enum.GetName(typeof(ContextType), value);
}
}
and modified configuration file:
<unity>
<typeAliases>
<typeAlias
alias="contextType"
type="System.DirectoryServices.AccountManagement.ContextType,
System.DirectoryServices.AccountManagement, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</typeAliases>
<containers>
<containername="identitystores">
<types>
<typename="primary" type="IIdentityStore" mapTo="ActiveDirectoryIdentityStore" >
<lifetimetype="singleton" />
<typeConfig
extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement,
Microsoft.Practices.Unity.Configuration">
<constructor>
<param name="context" parameterType="string">
<value
value="Domain"
type="contextType"
typeConverter="Microsoft.AccountManagement.Extensions.ContextTypeTypeConverter,
Microsoft.AccountManagement.Extensions, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=4fd564a94067c21"/>
</param>
</constructor>
</typeConfig>
</type>
</types>
</container>
</containers>
</unity>
That’s it, now everything works just fine. HTH someone out there 🙂
by community-syndication | Jan 6, 2010 | BizTalk Community Blogs via Syndication
Greetings!
Tech%u00b7Ed North America 2010, takes place in New Orleans from June 7-10, 2010.
We would like to request Breakout Session topic ideas from product expects like yourself. We hope you will consider submitting one or more session ideas for BizTalk Server , in the Application Integration (AIN) track before the January 15 deadline.
Steps for Call for Content submissions:
- Go to: https://northamerica.msteched.com/CFT
- Enter RSVP Access Code RSVP10-AIN for Application Integration Track
- Complete all the fields and submit the topic/s you’re interested in presenting
- When returning to the Call for Content site, use the e-mail alias and password you entered when creating your Call for Content profile to review or edit your submission, or to submit another topic.
Deadline for Submissions: January 15, 2010
Following is the track descriptions. Please ensure that your sessions align with it:
Application Integration Track
Learn how Microsoft’s latest products and technologies can help your organization leverage the flexibility and cost effectiveness of Web service based development and composite applications.This track covers the products and technologies that are relevant to the challenges you face and how to use them in the context of building and managing business applications. BizTalk Server, Windows Server AppFabric, SharePoint and, of course, the capabilities in .NET (WCF, WF, ASP.NET) will be brought together to show you how to use them to solve real problems.
Additional Call for Content Information
Breakout Sessions are the primary way Tech%u00b7Ed attendees receive Microsoft content. These sessions are lecture-style presentations held in rooms seating anywhere from 200-1,200 people. Breakouts are 75-minutes in length and speakers use PowerPoint slides and demos; leaving 10-15 minutes at the end to answer questions. These sessions are recorded and available at Tech%u00b7Ed Online to all paid attendees from the other worldwide Tech%u00b7Ed conferences held during the 12 months following Tech%u00b7Ed North America.
Additional conference information
The following information will be helpful as you think about the session/s you are going to submit and, if selected, present at Tech%u00b7Ed.
Tech%u00b7Ed is Microsoft’s premier global conference designed to provide developers and IT professionals with the technical education, product information and community resources they need to design, develop, manage, secure, and mobilize state-of-the-art software solutions for a connected enterprise. Content focuses on current and soon-to-released (before June 2011) Microsoft products, technologies and services.
At Tech%u00b7Ed North America 2009, 30% of attendees were developers — programmers (41%), architects (28%), designers (20%), and developer managers (12%) — who wanted to dive deeper into the latest enterprise development solutions using Microsoft’s developer tools, frameworks, and platforms. The remaining 70 percent of Tech%u00b7Ed attendees were IT professionals with the majority being Infrastructure Managers (48%) and IT Mangers (28%). They were interested in the best ways to plan, design, deploy, manage and secure connected enterprise systems. The remaining
Review and notification
%u00b7 Session submissions are reviewed to determine which best meet the needs of the Tech%u00b7Ed audience, adhere to the Track framework and content focus, and fulfill the messaging requirements of the product groups.
%u00b7 Session selections will be made and you will be notified by e-mail in February 2010.
Thank you for your time. We look forward to seeing your Breakout Session ideas.
http://northamerica.msteched.com/