Generating a mock/stub WCF web service from a WSDL

When working on integration projects you sometimes need to build a stub or mock service to emulate the behavior of the targeted system in your dev environment.

Visual Studio’s Add Service Reference dialog provides an easy way for generating the client code based on the WSDL of the service that you are invoking. Unfortunately there is no such dialog to generate a server side stub / mock.

There are various approaches you can take here but using svcutil.exe has been the most pain-free for me.

Here’s an example of how to go about it: svcutil /mc UserService.wsdl UserTypes.xsd

The /mc parameter generates a class file with all the data types defined in the .xsd as well as the interfaces for all the operations defined in the WSDL. It also provides you with a starter .config file that you’ll then need to tweak to define the port on which the service is going to be hosted.

Once you have these files create a new WCF Service Library project, add the generated class files. Then create an implementation class that implements the interfaces that is generated. To keep things simple you might want to write code for just the operations that your calling from the client side.

Now here’s a gotcha for those stubbing out a service generated by Oracle WebLogic. The Action (SOAP Action) attribute on the operations are sometimes the same for all the operations in the interface. WCF doesn’t support this since it doesn’t conform to the WSDL specifications. You’ll easily know that you’ve hit this issue when you get the following exception when trying to host your stubbed service.

System.InvalidOperationException: The operations xxx and yyy have the same action (). Every operation must have a unique action value. at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ActionDemuxer.Add(String action, DispatchOperationRuntime operation) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime..ctor(DispatchRuntime dispatch) at System.ServiceModel.Dispatcher.DispatchRuntime.GetRuntimeCore() at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpened() at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout) at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)

To overcome this you can create a custom Dispatch Behavior that uses an alternate algorithm to assign incoming messages to operations. The Dispatch by Body Element WCF sample comes with a sample implementation that works well.

All you need to do is add the two class files in this zip file (it’s the same code that comes with the WCF samples) DispatchByBodyBehavior

Next open up the class generated by svcutil and add the DispatchByBodyBehavior attribute to the ServiceContractInterface. You should now be able to host the service in WCF without any issues.

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples"), DispatchByBodyElementBehavior] public interface IDispatchedByBody { [OperationContract(ReplyAction="*"), DispatchBodyElement("bodyA","http://tempuri.org")] Message OperationForBodyA(Message msg); [OperationContract(ReplyAction = "*"), DispatchBodyElement("bodyB", "http://tempuri.org")] Message OperationForBodyB(Message msg); [OperationContract(Action="*", ReplyAction="*")] Message DefaultOperation(Message msg); }

ULS Viewer stops working

If ULS Viewer suddenly stops reading from the ULS log, the quick fix is to move all the log files to another folder. Except for the last log file which Explorer will anyway prevent you from moving.

The issue is most probably because one or more files in the folder are not in the right format and trip up ULS Viewer.

Some have reported the *upgrade.log files as the culprit. Deleting them didn’t fix it for me so I just deleted all the files.

PS: If your a SharePoint dev and your not using the ULS Viewer from Microsoft (no not the one from CodePlex). Do yourself a favour and give it a try. http://archive.msdn.microsoft.com/ULSViewer

FBA Custom Sign In Page returns 401 Unauthorized error

If you’ve built a custom sign in page in SharePoint 2010 but keep getting a 401 Unauthorized error instead of the sign in page then you’ve most probably deployed the solution package to a single web application.

To resolve the issue the solution needs to be deployed to all applications and not restricted to a single web application.

i.e. When calling Install-SPSolution don’t include the -WebApplication parameter.

Edit: Another instance when you will see the 401 Unauthorized error is when your not inheriting from the correct base page. It should not be the layoutsbasepage.

Another tip if you see the following error in your ULS log: Request for security token failed with exception: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Object reference not set to an instance of an object. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.SPRequestInfo.ValidateFormsAuthProviderNames(Uri context, String membershipProvider, String roleProvider) at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.SPRequestInfo.SetProviderNames(RequestSecurityToken request) at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.SPRequestInfo..ctor(IClaimsIdentity identity, RequestSecurityToken request, Boolean initializeForActor) at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.SPRequestInfo..ctor(IClaimsPrincipal principal, RequestSecurityToken request) at Microsoft.SharePoint.IdentityModel.SPSecurityTokenService.GetTokenLifetime(Lifetime requestLifetime) at Microsoft.IdentityModel.SecurityTokenService.SecurityTokenService.Issue(IClaimsPrincipal principal, RequestSecurityToken r...).

That means your using a name that has not been setup as an AAM. I was using http://localhost and it always kept failing. Changing the request url to the actual name of the server (in my case http://mosswfe1) fixed it.

Note to myself: References for creating a Custom Sign In Page Creating a Custom Login Page for FBA in SharePoint 2010 Creating a Custom Login Page for SharePoint 2010 How to create custom login page for SharePoint 2010 form based authentication (FBA)

FBA Configuration Manager for SharePoint 2010

Setting up forms based authentication in SharePoint 2010 requires making changes in three web.config files.

This utility allows you to perform the update in a single click and was inspired by the configuration manager that Steve Peschka released.

I’ve taken a different approach to Steve’s, instead of using a feature and a timer job I directly update the config files in the local machine. To update the other machines in the farm you can use the included PowerShell script.

The utility makes a back-up of all of the web.configs before updating them. I’ve also included the sample membership and role providers that Steve provided.

The PowerShell script to perform the update uses the same engine as the UI.

function global:Get-ScriptDirectory() { $Invocation = (Get-Variable MyInvocation -Scope 1).Value Split-Path $Invocation.MyCommand.Path }

$webApp = Get-SPWebApplication http://localhost:9191 $settingsPath = Join-Path (Get-ScriptDirectory) “SqlMembershipConfig.xml” $settings = Get-Content $settingsPath $scriptDir = Get-ScriptDirectory $assemblyPath = Join-Path $scriptDir “FBA.dll” Add-Type -Path $assemblyPath [FBA.ConfigureMembershipProvider]::Configure($webApp, “Default”, $settings) </code>

The source code and release packages are available in CodePlex: http://fbaconfigmanager.codeplex.com/

Updating Extended Properties of a Database using SQL Server SMO

Updating the extended properties on a database using SQL Server’s excellent Server Management Objects API is not as straightforward as setting the value and calling update.

The database.Alter() method needs to be called both before and after updating the value. I had to lookup the code of El Pluto’s awesome SQL Server Extended Properties Quick Editor project on CodePlex to figure this out.

using Microsoft.SqlServer.Management.Smo;
 
/// <summary>
/// Set's the extended property of a database.
/// </summary>
/// <param name="serverName">The name of the SQL Server.</param>
/// <param name="databaseName">The name of the database.</param>
/// <param name="propertyName">The name of the extended property.</param>
/// <param name="value">The value of the extended property.</param>
private void SetExtendedProperty(string serverName, string 
    databaseName, string propertyName, string value)
{
    var server = new Server(serverName);
    var database = server.Databases[databaseName];
 
    database.Alter();
    if (!database.ExtendedProperties.Contains(propertyName))
    {
        database.ExtendedProperties.Add(
            new ExtendedProperty(database, propertyName, value));
    }
    else
    {
        database.ExtendedProperties[propertyName].Value = value;
    }
    database.Alter();
}
 

Dynamically setting multiple activity destinations in K2 with ASP .NET

When building a typical workflow you usually know which user or group needs to perform an activity at design time. Sometimes though the workflow needs to be more dynamic.

The issue I had to resolve recently involved having to build a workflow where the end-user gets to individually pick the users who will be performing the next step. Here’s a view of  the workflow design.

The scenario involved an application being submitted for review. The application would go to an individual who is responsible for assigning a group of users (destination users) to review the application. The twist was that it was the individual picking users for each application, it wasn’t a fixed group or role. The screen mockup shows how they do it.

When the person hits the ‘Assign Reviewers’ button the form then needs to turn up as a work list item for each of the reviewers (destination users) who get to review the application in parallel.

Implementing this process using K2/InfoPath is quite straightforward and is well documented in many places including this post titled ‘Activity Destination Users based upon a Repeating XML element’ in a K2 underground blog.

It’s not well documented though for ASP.NET. The post ‘How To: Use a web service for destinations in K2 blackpoint’ is close to what we want but it’s targeted at using a web service.

K2 let’s you set multiple destination users in one of two ways

  1. Using a SmartObject method in a role

  2. Using Xml as a destination set

Going the SmartObject route was a lot of work for my simple requirement so I chose the Xml method. The idea here is to use the list of users in the Assign Reviewers form and store them in a Process xml field. The destination set will then be configured to read the xml field and create a slot for each user.

FYI: See page 4 of the Advanced Destinations whitepaper for a description of the two roles. <rant>Why the K2 KB portal needs a login is beyond me.</rant>

Step 1: Write the code to create the xml containing the list of users

The code block below accepts a ; delimited list of domain name\username (e.g. domain\johna) and creates an XML document containing the list of users. This is then assigned to the Process Instance XML field called Reviewers.

private static void AssignReviewers(WorklistItem item, string listOfUsers)
{
    var doc = new XmlDocument();
    var root = doc.CreateElement("UserList");
    doc.AppendChild(root);

    foreach (string user in listOfUsers.Split(';'))
    {
        var userNode = doc.CreateElement("Users");
        userNode.InnerText = user;
        root.AppendChild(userNode);
    }
    item.ProcessInstance.XmlFields["Reviewers"].Value = doc.OuterXml;
}

Step 2: Create an xml schema based on the user list xml

This proved to be the trickiest part for me. Using the xsd.exe as documented in this article didn’t work.  After a lot of anguish I worked out that K2 was happy with the schema generated by InfoPath. So I opened an empty form in InfoPath and added a repeating text field (screenshot).

Next I exported the form to get to the .xsd (in InfoPath 2010 it is File -> Publish -> Export Source Files). Cleaning out the my: namespace and a bit of tweaking should give you the following schema definition. This definition should work fine with the xml produced by the above code block.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="UserList">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Users" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Step 3: Create an xml field for the process

Armed with the xml schema, we’re now ready to configure the workflow.

Fire up the K2 process designer and add the process xml field name Reviewers which we referred to in our code in step 1.

To do this open the Process General Properties window, expand the right panel. From the list select the Process/Activity Data node, expand it to select the name of your process and right-click on it to click Add.. and get to the Add XML Field.

Name the field ‘Reviewers’.

Switch to the XML Schema tab and browse to pick the xsd file created in Step 2.

When you hit OK you should now be able to drill down and see the Users node.

The key is to make sure that the node’s icon has a green overlay which flags it as a repeating node. If it’s there you should be fine. If not you need to repeat the steps above until you get the green overlay icon. Without it, the worklist item is not going to be assigned to multiple users.

Step 4: Setup the destination to read from the xml field

Select the activity which needs to be executed in parallel and click on the Destination Users node. Switch to the Advanced Mode if you are not already in there (select the checkbox on the first page). In the Destination Rule Options select Plan per destination ->All at once. We do this to tell K2 that when it goes to multiple users they will be able to open and work on the item in parallel.

Select ‘Create a slot for each destination’, this way each destination user get’s their own slot.

Click on the Edit button to configure the Destination sets.

Click on the ellipsis to open the Context Browser, drill down to the Process Xml field that we setup earlier and drag the Users repeating node (the one with the green icon) onto Name column.

You should now be all set to test out your dynamic multiple destination users! Running through the workflow you will now see that the worklist item gets assigned to each of the reviewers in parallel.

Limit SQL Server memory usage on your workstation, laptop or VM

Here’s a neat tip I learnt over the weekend.

All SQL Server instances are by default set up to use all the memory available on your workstation.

This is ideal when you have SQL Server running on it’s own dedicated server hosting, not so ideal when you have SQL Server installed on your laptop, workstation or even on a SharePoint VM.

Here’s what MSDN says

if SQL Server is one of several server applications running on a single computer, the system administrators may need to control the amount of memory allocated to SQL Server. In these cases, you can use the min server memory and max server memory options to control how much memory SQL Server can use.

In the Server Memory Options page they go on to say:

When you are running multiple instances of the Database Engine, there are three approaches you can use to manage memory
  • Use max server memory to control memory usage.
  • Use min server memory to control memory usage.
  • Do nothing (not recommended).

Which brings us to how we can set the maximum limit. Quite easy. Just connect to each SQL Server instance and set the maximum memory to a more palatable value.

Here’s a visual walk through to limit the maximum memory usage to 512MB for your SharePoint 2010 instance (if you installed it on Windows 7).

  1. Start SQL Server Management Studio (or SSMS Express) and connect to your SQL Server instance (SharePoint in this case): localhost\SharePoint

  1. Right-click on the instance node and select Properties.

  1. Click on the Memory node you’ll notice that the Maximum Server Memory is set to 2,147,483,647MB change it to a lower limit like 256 or 512MB. Click OK and your all set.

If you prefer SQL the same can be done with the following commands.


Enable advanced options:

USE master

EXEC sp_configure 'show advanced options', 1

RECONFIGURE WITH OVERRIDE


Set the maximum amount of memory to 512 MB:

USE master

EXEC sp_configure 'max server memory (MB)', 512

RECONFIGURE WITH OVERRIDE


Display the newly set configuration:

USE master

EXEC sp_configure 'max server memory (MB)'


Set ‘show advanced options’ back to default:

USE master

EXEC sp_configure 'show advanced options', 0

RECONFIGURE WITH OVERRIDE

Feature differences between SharePoint 2007 Enterprise and Standard for a Publishing Portal

I recently had to deploy a site template that was built using SharePoint Enterprise Edition 2007 on an instance of SharePoint Standard Edition 2007.

Obviously given that some features were not available in the Standard Edition I received the ‘The template you have chosen is invalid or cannot be found’. Unlike a MOSS to WSS conversion the problem here is that the features do exist on the server but are simply not available for the standard edition.

I basically resorted to manually comparing the differences between a site template created in the Standard edition vs one created in the Enterprise edition.

Here’s the list if anyone ever needs this.

Remove these features from a template created in the Enterprise edition if you want to deploy it on a Standard edition. Obviously you need to test to ensure that your template is not actually using any of the Enterprise features. <Feature ID="065c78be-5231-477e-a972-14177cc5b3c7" /> <Feature ID="0806d127-06e6-447a-980e-2e90b03101b8" /> <Feature ID="2510d73f-7109-4ccc-8a1c-314894deeb3a" /> <Feature ID="e8734bb6-be8e-48a1-b036-5a40ff0b8a81" /> <Feature ID="00bfea71-dbd7-4f72-b8cb-da7ac0440130" />

SQL Server 2008 Service Weirdness

Two weird things I learnt about SQL Server while building the SharePoint 2010 Service Manager.

1. SQL Server Agent service for SQL Express is bogus

Whenever Service Manager started, the SQL Server Agent service for the SharePoint (SQL Express) instance  would immediately stop with either of the following errors logged in the Windows Event Log.

  • The service cannot be started, either because it is disabled or because it has no enabled devices associated with it. [0x80070422]
  • SQLServerAgent could not be started (reason: Error creating a new session).

The self explanatory title of the bug filed on Connect says it all ‘SQL Express installs SQL Agent Service for no apparent reason’. Apparently the team cutting down features for the Express edition forgot to tell the Agent team that they weren’t needed in Express.

2. SQL Server VSS Writer Service : Startup Type get’s reset to ‘Manual’

The Service Manager has a feature that let’s you set the startup type of all the SharePoint and related services to Manual. This way they wouldn’t automatically startup when Windows starts hence leaving the workstation to boot faster.

The Service Manager only shows the ‘Stop Automatic Startup’ button if the Startup Type of any of SharePoint services are set to Automatic. While testing the feature I released that after sometime the button automatically showed up even after I had set all the services to start manually.

That was when I figured out that even if I manually change the service (through Control Panel) to start manually, something would change the startup to Automatic after a while. I haven’t figured out what changes it’s startup type to automatic but I’m guessing that’s by design. My workaround for the Service Manager was to ignore the startup type of the VSS Writer service when checking if all the services were set to manual.

SharePoint 2010 Service Manager

With the final release of SharePoint 2010, I finally had time to brush-up and release the Service Manager that I wrote sometime back when the 2010 betas was released.

This utility is basically akin to the SQL Server Service Manager of yore.

If you have SharePoint 2010 installed on your local Windows 7 workstation then you will definitely come across instances where your workstation suddenly freezes up and everything starts moving in slow motion. The most likely culprit is usually one of the SharePoint services. At other times the SharePoint services simply eat away at your RAM.

That’s where the SharePoint 2010 Service Manager comes into play. It lets you start and stop all the SharePoint Services running on your workstation with a single-click.

This release handles both the full version of SQL Server as well as SQL Express Edition (the SharePoint instance). There is also an option to permanently disable the SharePoint services from starting up when Windows starts up, hopefully leading to faster boot times.

Here are a couple of screenshots. Get the setup file from CodePlex at http://sharepointserviceman.codeplex.com/.

I’d like to thank my colleagues at UniqueWorld including Neil, Rehman and Dougie who tested the first version and gave valuable feedback.

Please do report any issues you find to merill at merill.net