Wednesday, May 25, 2011

The specified database is not a valid Monitoring database or is not available

During a rollout into production, the windows sys admin was responsible for executing the AppFabric installation scripts that I had put together, which includes using the Initialize-ASMonitoringSqlDatabase cmdlet, which allows you to create the monitoring database for AppFabric to use.
Just a reminder that the account running the script / cmdlet must be a sysadmin on the target SQL server, or you'll get the not a valid Monitoring database.... error, which we were getting.
More details are here.
The error message returned from the Initialize-ASPersistenceSqlDatabase cmdlet is a little more descriptive - Failed to connect to the master database on the SQL server.... Could not open a connection to SQL Server. However, this error message is caused for the same reason.

Monday, May 9, 2011

Default physical path when deploying web applications using MSDeploy

MSDeploy will use the physical location of the web site that the web application is being deployed under, if you're deploying a web application without specifying a physical location in the parameter settings.

Specifically, MSDeploy uses the physicalpath attribute for the site defined in the applicationHost.config file, which is located C:\Windows\System32\inetsrv\config.

So for example, my default web site is defined as physicalPath="E:\inetpub\wwwroot", which is specified in the virtualDirectory element. I have an application whose virtual path is under the default web site. When I deploy this application, which doesn't have a physical location specified as a parameter, it will use E:\inetpub\wwwroot as the base, and create a sub folder - e.g. E:\inetpub\wwwroot\NewApplication.

One thing to keep in mind, once the deployment has been performed, a new application element is created in the applicationHost.config file for the web application deployed. If you delete the application from IIS - the configuration remains for the application. This is key to remember, as this will now become the default physical location for the application, regardless of the physical location of the default web site. So if you want MSDeploy to use the default web site's physical address as the base address (assuming your deploying your applicaion under DWS), then you'll have to manually delete the application element for the web application in the applicationhost.config file before executing the deployment.

Monday, May 2, 2011

IErrorHandler.ProvideFault & serialization issues using XmlSerializer

I'm pretty much repeating what I posted here on the MSDN forum, but my work around seems to be doing fine so I thought it's worth noting down in case someone else comes across this problem.

If you're using the XmlSerializer rather than the default DataContractSerializer, beware that once you are out of the context of the service implementation (i.e. in a behaviour), WCF will use the DataContractSerializer. Why is this a problem?

Well, if you have implemented IErrorHandler, and are recreating the fault message that is returned to the client (e.g. using the CreateMessageFault method from the FaultException instance), the message has been serialized again. The trouble is, there is no way as far as I am aware of specifying which serializer to use (hence the reason for my post on MSDN) and WCF resorts back to its default of the DataContractSerializer.

I'm using a fault contract when creating the FaultException - i.e. FaultException and my ErrorInfo type in decorated with the appropriate Xml attribute indicating its Xml type and namespace. Eg:

[XmlType("ErrorInfo", Namespace="http://FaultContract")]
public class ErrorInfo

When this is returned back to the client, a different namespace arrives for the ErrorInfo type (rather than FaultContract), which means the client can't deserialize it. The xml namespace instead is http://schemas.datacontract.org/2004/07/ etc which is not what the client is expecting.

The reason this is happening is that the DataContractSerializer is looking for the DataContract attribute to determine what to use for the xml namespace. Since the ErrorInfo type isn't decorated with this attribute, which makes sense - I'm not using the DataContractSerializer, a default namespace is used instead.

To fix this, I have decorated the ErrorInfo type with both the XmlType attribute, and DataContract attribute:

[DataContract(Name="ErrorInfo", Namespace="http://FaultContract")]
[XmlType("ErrorInfo", Namespace="http://FaultContract")]
public class ErrorInfo

This now handle both scenarios, the Fault message created within the context of the service (where you can specify the serializer to use), and the Fault message created within a behaviour.
This took me a while to determine why this was occuring, but eventually I was able to isolate where the problem was (the behaviour). When I turned the IErrorHandler behaviour off, the client was able to deserialize the ErrorInfo type correctly (as the correct namespace was used).