Nicholas Allen's Indigo Blog

Windows Communication Foundation From the Inside

July, 2007

  • Nicholas Allen's Indigo Blog

    Four Hundred and First Post

    • 2 Comments

    Continuing the series of milestones, Monday marked the 400th post. With the small number of days having multiple posts and the very small number of days having no posts, that has as expected worked out extremely near to exactly one post per weekday for 18 months. Amazingly, 306 of those posts have managed to be about WCF. When I first started, I expected to get no more than a few dozen posts before having to switch to other topics. That will not be necessary any time soon.

    The next milestone to be celebrated will be after 800 posts, so you can expect this to occur on approximately March 9th, 2009.

    Here are the milestone dates so far:

    • 1st post- February 6th, 2006
    • 101st post- June 13, 2006
    • 201st post- October 24, 2006
    • 401st post- July 31st, 2007
  • Nicholas Allen's Indigo Blog

    Configuration Quick Reference

    • 4 Comments

    Several people have asked me about configuration questions that could have been resolved by looking at the format for configuration files. The SDK actually has a very nice diagram covering all of the different configuration nodes although it doesn’t have the individual key values. It seems to be hard to find so I've linked to a copy here. You may need to save the image locally if your reader doesn’t let you view large images at their native size.

    Next time: Revealing the Hierarchy

  • Nicholas Allen's Indigo Blog

    Orcas Beta 2 Released

    • 3 Comments

    The second full public beta of the .NET Framework 3.5 came out this week. The final version should be out sometime around the end of the year. Unlike previous releases, I can't find an online link to the release notes or known issues. I'll update this post later if I come across it. Here is the direct download:

    Update: Thanks to Jin Miao for finding links to the release notes.

  • Nicholas Allen's Indigo Blog

    Message Disposal

    • 1 Comments

    My service operation has an untyped contract and I'm trying to save the messages that it receives for processing later. However, the messages always say that they are closed before I can read them. Why are the messages closed?

    Messages are good for a single use, which means that once someone has finished with the message, no one else can read it even if there are multiple references pointing to the same message object. Most commonly, the service is responsible for reading and closing the messages. If you have a typed contract, then the service has to read the message to produce the types. If you have an untyped contract though, the service can hand the message to you without having read it. In either case, the service takes responsibility for closing the message after the service operation completes. This prevents you from having to think about the messages and clean up after them.

    When you intend to process a message later, it's clearly not a good thing for the service to think that it is responsible for closing the message after the service operation completes. You can tell the service that you want to take control of cleaning up messages so that the service does not have this responsibility. To mark service operations for manual cleanup, add an OperationBehavior attribute to the service operation implementation that sets AutoDisposeParameters to false. It is now entirely your responsibility to clean up messages after processing is complete.

    Next time: Configuration Quick Reference

  • Nicholas Allen's Indigo Blog

    Data Contract and Message Contract

    • 1 Comments

    I have an existing web service that I need to replace with a WCF web service. How do I choose between using a data contract and a message contract?

    There are actually three choices to consider for describing the messages that your service uses: data contracts, message contracts, and XML serialization. You will be forced to use XML serialization in some cases because you have an existing message format with precise specification of XML elements and attributes that you need to replicate. In these cases, it may simply be impossible to duplicate this exact XML schema with a message or data contract-based description, forcing you to use XML serialization to describe the messages.

    However, let's assume that the existing message format is not so unreasonable and you have a choice between the various options for describing messages with contracts. How do you choose between data contracts and message contracts? The choice may not always seem clear if both types of contracts are capable of describing your messages. A rule of thumb though is that data contracts are generally portable between different kinds of XML encodings, making this option preferable if you might choose to project the Infoset differently in the future. Message contracts are more limited in the projections that they can support but are reasonably adept at mimicking the most common types of XML messages produced today.

    Therefore, there is a preference to use data contract, followed by message contract and XML serialization. However, the ability to adapt to a preset form is ranked in the reverse order. When you're required to conform to an existing message layout, you are more likely to be forced to use message contracts. When you are designing new message layouts, you almost always want to use data contracts.

    Next time: Message Disposal

  • Nicholas Allen's Indigo Blog

    Listener Won't Start Bonus Tip

    • 0 Comments

    As a followup to yesterday's post on resolving listener and activation errors, here's an additional point to consider while attempting to diagnose a problem. Once you've found where the failure symptoms first appear, whether that be in the service, the listener, or in the host application, you still have to do some more searching to find the root cause of the failure. This is always true when debugging, but it's a particular issue when you're trying to diagnose the cause of failure based on an indirect observation, such as a service not starting, rather than a direct observation.

    As an example, consider the basic case where IIS is running successfully for HTTP services but your non-HTTP services won't activate. Your services have two dependencies, one pointing towards the service configuration and another pointing towards the infrastructure. Following the dependency tree towards the infrastructure, it has multiple dependencies, one pointing towards the specific protocol listener that receives the first message and another pointing towards WAS, which performs the generic process management. The specific protocol listener in turn has more dependencies, such as the configuration, the application pools using the listener, and so on.

    Diagnosing problems quickly becomes a learned skill based on building a mental model for how the activation components work in sequence. This is another reason why I recommended having a particular order of investigation in the previous post because it's easier to pin the blame on a component when you can rule out the cause being that component's dependencies.

  • Nicholas Allen's Indigo Blog

    Listener Won't Start

    • 1 Comments

    Here's a debugging tip for those of you that are developing non-HTTP web services on top of IIS7. IIS7, which comes with Vista and Windows Server 2008, allows you to host activatable services using arbitrary network protocols. WCF ships with protocol handlers for TCP/IP, MSMQ, and named pipes. What do you do though when service activation fails?

    First, check the type of error that you're seeing on the client. It should be an EndpointNotFoundException or other similar exception type that tells you that absolutely no application-level processing of the message occurred. If your application can receive messages, then you probably don't have an activation problem. You should obviously make sure that the configuration for the client is correct before proceeding.

    Second, check the event and application logs on the server machine to see if they tell you what has gone wrong. You may have to turn on logging if you don't normally run with it enabled. The event log tends to be a particularly useful source of information for activation errors.

    Third, if the logs don't give you enough information, then start attempting to manually diagnose the problem. I generally work from the outside in, making sure that the big systems, like IIS, function at all before paying attention to the little systems, like my service. If you have other services that work correctly, then you can usually blow through these stages really quickly until you get down to the service level checks.

    Fourth, if manual diagnosis fails, then start attempting to manually debug the problem. I really recommend that you don't get the debugger out until you've exhausted your other options. You might do some casual debugging to catch exceptions during diagnosis but intense debugging sessions are rarely the fastest way to find the problem.

    Next time: Data Contract and Message Contract

  • Nicholas Allen's Indigo Blog

    Top Content

    • 0 Comments

    I'm thinking about including lists like these in the sidebar, but I wanted to try this out once first. Subscriptions mean that the number of RSS readers is more or less the same for articles posted around the same time. Therefore, I'm defining top content in terms of how popular an article is to be the number of times clicked through by web users. Of course, this biases things quite a bit towards articles that have interesting content that people want to visit multiple times.

    Top Content- Last 30 Days

    Michele's Webcasts Start Monday

    WCF Case Studies

    Orcas Beta 1 Released

    Inside the Standard Bindings: NetTcp

    Configuring HTTP for Windows Vista

    Changing the ChannelFactory Contract

    Net.Tcp Port Sharing Sample, Part 1

    Top Content- Last 6 Months

    Configuring HTTP for Windows Vista

    MSMQ and Poison Messages

    Net.Tcp Port Sharing Sample, Part 1

    Inside the Standard Bindings: NetTcp

    Inside the Standard Bindings: BasicHttp

    Net.Tcp Port Sharing Sample, Part 2

    Preventing Anonymous Access

  • Nicholas Allen's Indigo Blog

    Svcutil Tips

    • 2 Comments

    Two answers in one today on the subject of svcutil.

    How do I merge together configuration files like Visual Studio does with multiple web references?

    Use svcutil.exe with the /mergeConfig option.

    How do I pass credentials when accessing metadata from a secure endpoint with svcutil?

    You can create a configuration file for svcutil.exe that allows you to specify options such as credentials just like any other application. If your credentials can only be set through code rather than configuration, then create a behavior that sets up the credentials and add that behavior to the configuration file for svcutil.exe.

    Next time: Listener Won't Start

  • Nicholas Allen's Indigo Blog

    Enabling Performance Counters

    • 5 Comments

    Performance counters are a mechanism for monitoring services that you can get without changing any code, but you have to ask for them. The values of performance counters give you real-time monitoring information about the operational characteristics of your services. You can control performance counters through configuration.

    <system.serviceModel>
    <diagnostics performanceCounters="All" />
    </system.serviceModel>

    The possible settings for the scope of service counters are Off, ServiceOnly, and All. For the actual performance counters, the scopes are finer grained, with different naming schemes depending on the type of data that the performance counter monitors.

    • Service scope performance counters look like Service@Address
    • Endpoint scope performance counters look like Service.Contract@Address
    • Operation scope performance counters look like Service.Contract.Operation@Address

    The address is based on the external address of the object being monitored, with some modifications. The addresses are normalized by capitalizing them, replacing certain characters (the forward path separator is replaced by a pipe symbol, for example), and then mangling the address so that it is both short and unique. Addresses that are already short remain essentially readable while addresses that are more than a few dozen characters come out considerably worse for wear.

    Next time: Svcutil Tips

  • Nicholas Allen's Indigo Blog

    A versus B

    • 6 Comments

    It's felt like there have been a lot of articles based on answering reader questions lately. And, when I checked the totals, I noticed that the next Answers column would be the 100th. Since I started running answers to questions a little less than a year ago, then assuming around 240 posts per year, that means that a bit less than half of all articles over the course of a year have been about answering questions. I started running answers to questions based on reader feedback so it would be interesting to know whether people still like the idea. Would you rather:

    • Have more answers to questions and fewer original articles?
    • Have more original articles and fewer answers to questions?
    • Have equal amounts of both?
  • Nicholas Allen's Indigo Blog

    Local Settings and Policy

    • 1 Comments

    You have talked in the past about how a service has both local settings and settings that are shared through policy. How can I transmit all settings through policy to the client?

    The two types of settings are clearly distinguishable.

    • Shared settings are required to have agreement between the client and server for the two to interoperate. Examples of shared settings are the protocols and formats being used to transmit messages.
    • Local settings are not required to have agreement between the client and server for the two to interoperate. Examples of local settings are the limits for the time and space allowed to process a message.

    Local settings can not only be in disagreement between the client and server, but they frequently do not make sense to share between the two. The messages sent between the client and server are rarely symmetric. The processing resources available to the client and server are rarely the same. The security concerns of the client and server are rarely in agreement.

    You can transmit local settings by creating your own policy assertions that both sides implement. This will involve a lot of hassle, particularly if the service wants to have local setting values that are different than those sent in the policy. Finally, the client will need to absolutely trust the service because you are asking the user to run with settings that were supplied by a third party. Why do you want to do this using policy? It seems that if you have such a level of trust with the client, then you probably already have more direct ways of pushing configuration and executables to the client machine.

    Next time: Enabling Performance Counters

  • Nicholas Allen's Indigo Blog

    Sticky Sessions

    • 1 Comments

    How can I use reliable messaging together with a load balancer?

    The point of reliable messaging is to help ensure that messages get from one place to another. This means that the protocol notices when messages that were expected to be delivered go missing. On the other hand, the point of a load balancer is to make sure that messages are spread out and that there aren't too many messages going to the same place. You can see how these two goals might come into conflict at times.

    Many load balancers do offer a compromise to make these two goals simultaneously achievable though. A perfect load balancer would take the total sum of messages delivered and divide those messages evenly up among the available processing nodes. However, assume that the number of messages in any one client session is relatively small compared to the total number of messages processed. A load balancer could instead apportion groups of messages among the available processing nodes where the total sum of messages is still split roughly equally. This division according to groups would allow a feature like reliable messaging to work because the same server would be used to process all of the messages in the reliable session. The feature that this division method represents is typically called "sticky sessions" or some other phrase for affinitization in the load balancer.

    Next time: Local Settings and Policy

  • Nicholas Allen's Indigo Blog

    Contact

    • 0 Comments

    I get quite a few messages through the email contact form- usually at least a dozen per week that ask questions about WCF. For the past year, I've been able to reply to nearly all of these with a wait of no more than about 1-2 weeks. By the way, if you have a question that you'd like to get answered sooner, then you can frequently have responses within hours when posting to the WCF forums. When you use the contact form though, you need to give a valid email address if you'd like me to respond. If you leave it blank or put the wrong address in, I have no way to contact you. Many questions eventually get posted as articles but that generally happens months after I've received the question.

  • Nicholas Allen's Indigo Blog

    Reader Quotas with Untyped Messages

    • 1 Comments

    I have an operation contract that uses untyped messages. When using the message, I get an error telling me to change the quota settings on the XmlReader. Where are these quotas located? I'm not using an XmlReader.

    A message represents an XML InfoSet. While there are many different ways to access the content of a Message, in a standard implementation, all of these methods are wrappers around the core XmlReader and XmlWriter infrastructure. If there is no obvious XmlReader, then that means that the XmlReader is being used by the internal implementation of the message. Therefore, whoever created the Message must have been the one that knew about the XmlReader and its quotas. Since most of the messages that you deal with inside of a service operation were created by the message encoder of the binding, the first place to look for the quota settings are either on the binding or the binding element.

    Next time: Sticky Sessions

  • Nicholas Allen's Indigo Blog

    ChannelFactory Behaviors

    • 6 Comments

    How do I attach a custom behavior to a dynamically generated proxy object?

    This one should be easy if you've read the past two articles about modifying a ChannelFactory after creation. Although behaviors can't be specified while creating the ChannelFactory, the ChannelFactory has a local endpoint object that can have behaviors attached. Changing the endpoint for behaviors works exactly the same as changing the endpoint for contracts. As with all modifications to endpoints though, you need to make all changes prior to calling Open (or the first call with proxies) or you'll find that the endpoint has become immutable.

    Next time: Reader Quotas with Untyped Messages

  • Nicholas Allen's Indigo Blog

    WS-Policy 1.5 Proposed

    • 0 Comments

    On Friday morning another one of the web services standards being worked on at the W3C moved to the Proposed Recommendation stage. WS-Policy defines a language for web service requirements and capabilities that can be used together with other description languages, such as WSDL. Many other standards, such as addressing and security, make use of policy assertions to communicate how clients should be configured to achieve compatibility and interoperability with a web service. Work on WS-Policy has moved fairly quickly compared to WSDL- it was submitted to the W3C just over a year ago.

    The review period for WS-Policy 1.5 ends no sooner than August 17th. Based on recent standards work though, you shouldn’t rely on seeing any significant extensions to that date.

  • Nicholas Allen's Indigo Blog

    WCF Case Studies

    • 2 Comments

    The Microsoft case study site is a collection of easily-digestible executive-style summaries of people using Microsoft products. While ordinarily this may not sound all that interesting, case studies are good sources of easily stealable material whenever someone asks you to justify why you're using a particular technology. Of course, finding the case studies about WCF in the collection is next to impossible as WCF is not in the case study product list and all of the relevant keyword searches produce either far too few or far too many results to be what you're looking for.

    Rather than making you search for case studies, I have a selected collection of case studies that deal strongly with WCF. I have filtered these case studies so that they all were published around the time that WCF was finished or later. Obviously though, many of the case studies will be based on prerelease software as it takes a considerable amount of time to complete a project and then complete the case study.

    1. Avaya
    2. Choicelinx
    3. Crutchfield
    4. FNAC
    5. Kiwibank
    6. Nike
    7. OPC Foundation
    8. OTTO
    9. Pfizer
    10. Schneider Electric
    11. ST Electronics
    12. Commonwealth of Massachusetts
    13. Thomson Financial
    14. Thomson Tax and Accounting
    15. Tyco Fire and Security

    Next time: ChannelFactory Behaviors

  • Nicholas Allen's Indigo Blog

    Adding HTTP Headers

    • 2 Comments

    Why doesn't anything happen when I try to add HTTP headers from a message encoder?

    The problem here is a basic issue of timing. Recall the interface contract that a message encoder has with its transport. The transport receives a message from the next channel up in the channel stack, does some processing on the message, and calls WriteMessage on the message encoder when it wants to write out the message body.

    The message encoder does not necessarily see all of the message content. Some message content, such as framing, is independent of the message encoding and directly handled by the transport. In fact, the message encoder may not be called at all if there is no content for it to write. HTTP headers are an example of content that is handled by the transport rather than the message encoder. The message encoding transforms the body of the message, but HTTP headers are always sent as text.

    In the call to WriteMessage, the message encoder does get a Message object, which has a handle to the HTTP headers. However, if you look at the format of a raw HTTP message, then you would see that the HTTP headers are completely written out before the message body is written out. When streaming an HTTP message, the headers may even be transmitted before the message body is written out. Therefore, you should guess that it's unlikely that the message encoder can do anything with the HTTP header collection because the HTTP headers may already have been transmitted.

    If you want to change the HTTP headers, then you should make sure that all of the changes are made before the transport is given the message.

    Next time: WCF Case Studies

  • Nicholas Allen's Indigo Blog

    WS-ReliableMessaging 1.1 Completed

    • 1 Comments

    I thought I posted this right after the ratification announcement, but evidently I ran Spot the Intern instead. WS-ReliableMessaging 1.1 is the OASIS standardized version of the protocol for transferring messages reliably despite node or network failures. Reliable Messaging includes duplicate detection and elimination, message ordering, and guaranteed message delivery. WCF can make use of Reliable Messaging for recovering from network failures although the implementation today doesn't include support for recovering from node failures. The Orcas release of WCF has updates for this newly ratified standard.

    You can get a copy of the WS-ReliableMessaging 1.1 standard from the OASIS website.

    Next time: There's no post for the 4th of July.

  • Nicholas Allen's Indigo Blog

    ChannelFactory Contract and Generated Types

    • 4 Comments

    Last Monday we had an introduction to the contract associated with a ChannelFactory. Today's article is a tangential continuation of that discussion. Let's take a look at the typed version of the contract for the same echo service that we had before.

    [ServiceContract(Namespace="")]
    public interface IService
    {
    [OperationContract(Action="Echo")]
    string Echo(string text);
    }

    public class Service : IService
    {
    public string Echo(string text)
    {
    return text;
    }
    }

    I've set the namespace and action to specific values here just to make the service call simpler. Now, here's a service that uses a metadata exchange connection to get the service metadata for the IService contract. Using the metadata, we can create the same IRequestChannel interface to the service that we had last time. What is different here of course is that the format of the message has to change because the service really is using a typed contract.

    string uri = "http://localhost:8000/service";
    string mex = "http://localhost:8000/mex";
    Binding binding = new CustomBinding(new HttpTransportBindingElement());

    ServiceHost service = new ServiceHost(typeof(Service));
    service.Description.Behaviors.Add(new ServiceMetadataBehavior());
    service.AddServiceEndpoint(typeof(IService), binding, uri);
    service.AddServiceEndpoint(typeof(IMetadataExchange), binding, mex);
    service.Open();

    MetadataExchangeClient client = new MetadataExchangeClient(new EndpointAddress(mex));
    MetadataSet metadata = client.GetMetadata();
    WsdlImporter importer = new WsdlImporter(metadata);
    ServiceEndpointCollection endpoints = importer.ImportAllEndpoints();
    ChannelFactory<IRequestChannel> factory = new ChannelFactory<IRequestChannel>(endpoints[0]);
    IRequestChannel channel = factory.CreateChannel();
    XmlReader reader = XmlReader.Create(new StringReader("<Echo><text>a message</text></Echo>"));
    Message message = Message.CreateMessage(binding.MessageVersion, "Echo", reader);
    Console.WriteLine(channel.Request(message));

    message.Close();
    factory.Close();
    service.Close();

    The attempt to invoke the service fails with a different InvalidOperationException this time: "Instance of MessagePartDescription Name='text' Namespace='' cannot be used in this context: required 'Type' property was not set."

    Why is there a missing Type property for the contract definition? The lack of types is because the dynamic metadata generation call does not create the runtime contract types needed to describe the typed message parameters of the service operation.

    You might be able to spot two ways that this problem can be fixed. On the client end, the problem is that we don't have runtime types in the generated contract description. The only reason someone looked at the generated contract description is because we're implicitly using the contract to bootstrap the creation of the ChannelFactory. We don't actually need the contract because everything is hidden behind IRequestChannel. The ChannelFactory constructor has an alternative overload to just take the address and binding but not the contract. If we use that overload, then we can completely sidestep the problem and get back the expected message.

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
    <a:Action s:mustUnderstand="1">urn:IService/EchoResponse</a:Action>
    <a:RelatesTo>urn:uuid:8976d9b5-92c5-4491-aa2b-a1d293552f11</a:RelatesTo>
    </s:Header>
    <s:Body>
    <EchoResponse>
    <EchoResult>a message</EchoResult>
    </EchoResponse>
    </s:Body>
    </s:Envelope>

    On the server end, the problem is that we need to describe typed message parameters for a contract. If all of the clients are going to be accessing the service through an untyped interface, then it may make more sense to use an untyped contract for the service operations. An untyped contract would use the same message structure that we had last week and entirely avoid the issue of runtime contract types.

    Next time: Adding HTTP Headers

Page 1 of 1 (21 items)