May 2009 - Posts

WCF CommunicationObjectFaultedException " cannot be used for communication because it is in the Faulted state" MessageSecurityException "An error occurred when verifying security for the message"

I've just spent a couple of hours trying to track down a customer issue with one of our WCF services. Below was part of the unit test I was suing to test the service.

using (var client = new MemberServiceClient())
{
    client.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings["username"];
    client.ClientCredentials.UserName.Password = ConfigurationManager.AppSettings["password"];
    client.CreateMember(mem);
    client.DeleteMember(mem.ExternalRef);
}

and the exception it was throwing was:

failed: System.ServiceModel.CommunicationObjectFaultedException : The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
	
	Server stack trace: 
	at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
	
	Exception rethrown at [0]: 
	at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
	at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
	at System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
	at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
	at System.ServiceModel.ClientBase`1.Close()
	at System.ServiceModel.ClientBase`1.System.IDisposable.Dispose()

When I debugged the code the code actually fails at the CreateMember line not at the close method indicated at by the stack trace. Then I realised that this was one of thoes WCF silly moments - don't use using blocks!. Yes believe it or not if you use a using block around a WCF client and it fails when the using block calls the dispose method it throws a new excpetion masking the real exception.

 

The code below is some helper methods we use for making WCF clients are cleaned up correctly.

 

/// <summary>
/// WCF proxys do not clean up properly if they throw an exception. This method ensures that the service proxy is handeled correctly.
/// Do not call TService.Close() or TService.Abort() within the action lambda.
/// </summary>
/// <typeparam name="TService">The type of the service to use</typeparam>
/// <param name="action">Lambda of the action to performwith the service</param>

public static void Using<TService>(Action<TService> action)
	where TService : ICommunicationObject, IDisposable, new()
{
	var service = new TService();
	bool success = false;
	try
	{
		action(service);
		if (service.State != CommunicationState.Faulted)
		{
			service.Close();
			success = true;
		}
	}
	finally
	{
		if (!success)
		{
			service.Abort();
		}
	}
}

 

Changing the code to using our service helper methods.

 

ServiceHelper.Using(
    client =>

        {
            client.ClientCredentials.UserName.UserName = ConfigurationManager.AppSettings["username"];
            client.ClientCredentials.UserName.Password = ConfigurationManager.AppSettings["password"];
            client.CreateMember(mem);
            client.DeleteMember(mem.ExternalRef);
        }
    );

 

Now the code exposed the actual exception that was causing the issue.

 

failed: System.ServiceModel.Security.MessageSecurityException : An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
  ----> System.ServiceModel.FaultException : An error occurred when verifying security for the message.
	
	Server stack trace: 
	at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
	at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
	at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
	at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
	at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
	at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
	at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
	at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
	at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
	at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
	at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
	at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
	at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
	at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)


This exception had me stumped as I had never come across it before but after a bit of digging I discovered that the server time was 7 minutes late and that changing the time fixed the issue. Still trying to figure out how the server's time got out of synced.

Posted by Damien McGivern with 7 comment(s)
Filed under: ,

XML Linq requires correct namespace for all XElements

I've been teaching myself ASP.Net MVC during any free time I get at the weekends. I started a simple test project which has developed into the events section on NIMTUG. Yesterday I was looking for a way to easily create search engine sitemaps for the event and sepaker pages and I found Robert Tennyson's post Dynamic sitemaps with ASP.NET MVC which seems very easy indeed. With a couple of changes I had the sitemaps working and so submitted them to google only to be notified a couple of hours later that they had failed with the error "Invalid Namespace".

I should have validated the outputed Xml using the Google Sitemap Validator but instead I had only tested the xml output in the browser which hid the root namespace (xmlns attribute) but more importantly also hid an empty namespace on all the url elements.

 

<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url xmlns="">
    <loc>http://nimtug.org/events/speaker/details/41</loc>
   <lastmod>2009-05-23</lastmod>
  </url>
  <url xmlns="">
    <loc>http://nimtug.org/events/speaker/details/23</loc>

    <lastmod>2009-05-23</lastmod>
  </url> 

 

It appears that with LINQ to XMl you have to add the correct namespace to every XmlElement which seems like over kill to me as the child elements are supposed to inherit their namespace from their parent (as you would expect) - if anyone knows of an easier way please let me know. My fix was to just add the namespace to each XElement constructor.

protected string GetAlsoluteUrl(object routeValues)
{
    var values = new RouteValueDictionary(routeValues);
    var context = new RequestContext(HttpContext, RouteData);

    string url = RouteTable.Routes.GetVirtualPath(context, values).VirtualPath;

    return new Uri(Request.Url, url).AbsoluteUri;
}

protected ActionResult CreateSiteMap<TModel, TID>(IEnumerable<TModel> items, Func<TModel, TID> getID,
                                                  string controllerName, string actionName)
{
    // XML LINQ requires that ALL XElements have the correct namespace 
    XNamespace xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";

    var root = new XElement(xmlns + "urlset");
    foreach (TModel item in items)
    {
        object routeValues =
            new
                {
                    id = getID(item),
                    controller = controllerName,
                    action = actionName
                };


        // only add last modified element if we can get the date
        XElement lastMod = null;
        var lm = item as IObjectTimes;
        if (lm != null)
        {
            lastMod = new XElement(xmlns + "lastmod", (lm.Updated ?? lm.Created).ToString("yyyy-MM-dd"));
        }
        root.Add(new XElement(xmlns + "url",
                              new XElement(xmlns + "loc", GetAlsoluteUrl(routeValues)), lastMod
                     )
            );
    }


    using (var memoryStream = new MemoryStream())
    {
        using (var writer = new StreamWriter(memoryStream, Encoding.UTF8))
        {
            root.Save(writer);
        }

        return Content(Encoding.UTF8.GetString(memoryStream.ToArray()), "text/xml", Encoding.UTF8);
    }
}
Posted by Damien McGivern with 1 comment(s)
Filed under: , ,

PDF SQL Server Cheat Sheet

MVP Pinal Dave has posted his SQL Server cheat sheet as a PDF download.

Posted by Damien McGivern with no comments
Filed under:

My Phone public beta opens

Microsoft has opened the beta of the My Phone service to the public. Only Windows Mobile phones with version 6 and up are supported.

It allows you to backup you data and access it from you My Phone web account and more

Microsoft My Phone

Posted by Damien McGivern with no comments
Filed under: