Nicholas Allen's Indigo Blog

Windows Communication Foundation From the Inside

February, 2008

  • Nicholas Allen's Indigo Blog

    Runtime Limits in IIS

    • 2 Comments

    Does the IIS HTTP runtime configuration affect a WCF application?

    Yes, when the application is using IIS to host its HTTP endpoints. A WCF application that lives in IIS is an IIS application as well, even if you aren't explicitly using ASP.NET compatibility mode. Now, most of the settings for IIS don't make as much sense for WCF as for general web applications, but if you look at the httpRuntime configuration element, then you'll see some that apply.

    <configuration>
    <system.web>
    <httpRuntime
    executionTimeout="110"
    maxRequestLength="4096"
    requestLengthDiskThreshold="80"
    useFullyQualifiedRedirectUrl="false"
    minFreeThreads="8"
    minLocalRequestFreeThreads="4"
    appRequestQueueLimit="5000"
    enableKernelOutputCache="true"
    enableVersionHeader="true"
    requireRootedSaveAsPath="true"
    enable="true"
    shutdownTimeout="90"
    delayNotificationTimeout="5"
    waitChangeNotification="0"
    maxWaitChangeNotification="0"
    requestPriority="Normal"
    enableHeaderChecking="true"
    sendCacheControlHeader="true"
    apartmentThreading="false"
    />
    </system.web>
    </configuration>

    The setting that is most common to impact a WCF application is the runtime limit on maxRequestLength. This setting is intended to limit people making large file uploads but the usage patterns of web services seem to make it more likely for people to build applications with large request messages than in traditional HTTP applications. Note that the setting is specified in kilobytes so it is by default much larger than the maximum received message size in WCF. However, if you're dealing with messages of more than a few megabytes, you may run into this limit and be puzzled why your messages are failing even though the application quotas are sufficient.

    Next time: Sending to MSMQ with Integrated Authentication

  • Nicholas Allen's Indigo Blog

    TechEd Developer 2008 First Looks

    • 0 Comments

    I noticed the other day that the TechEd sites have started getting an extensive collection of session titles although it looks like no other descriptions are available. I'm just taking a guess about what most of these talks are going to be about, but I'm predicting that this audience will find these talks from the TechEd Developer half of the conference interesting. I haven't tried to figure out the Silverlight talks yet because those are too hard to predict from just the titles.

    WCF

    • AJAX-Enable Your Windows Communication Foundation Services
    • Building Federated Solutions on the Internet Service Bus
    • Building RESTful Services Using Windows Communication Foundation 3.5
    • Building Secure Web Services Using Windows Communication Foundation
    • Durable Windows Communication Foundation Services
    • Integrating Business Applications with Windows Communication Foundation
    • Productive Windows Communication Foundation
    • Providing Load Balancing, Application-Level Failover, and Centralized Configuration Management with Windows Communication Foundation Services and Microsoft .NET Applications

    WF

    • Building Human Workflows with Windows Workflow Foundation State Machines
    • Getting Workflows Running and Talking in Your Applications

    BizTalk

    • Degrees of Freedom Port Binding in Microsoft BizTalk Server
    • Microsoft BizTalk in the Supply Chain: Providing Supply Chain Visibility with EDI and Business Activity Monitoring
    • Windows Communication Foundation Adapters in Microsoft BizTalk Server 2006 R2
    • Framework and Microsoft BizTalk Best Practices with an Eye Toward "Oslo"

    CardSpace

    • What's New with Windows CardSpace in the Microsoft .NET Framework 3.5
  • Nicholas Allen's Indigo Blog

    Silverlight 2.0 Beta is Coming

    • 2 Comments

    Scott Guthrie revealed details about the Silverlight 2.0 release last week including that a public beta is coming soon.

    Here are the details that you probably care about:

    • The full download for the Silverlight beta release is a bit more than 4 MB
    • Silverlight runs in a variety of browsers and on both OSX and Windows
    • The beta includes a subset of the WCF client libraries including the ability to create proxies and call WCF endpoints

    Scott also has a number of tutorials published about writing a Silverlight sample application.

    1. Part 1: Creating "Hello World" with Silverlight 2 and VS 2008
    2. Part 2: Using Layout Management
    3. Part 3: Using Networking to Retrieve Data and Populate a DataGrid
    4. Part 4: Using Style Elements to Better Encapsulate Look and Feel
    5. Part 5: Using the ListBox and DataBinding to Display List Data
    6. Part 6: Using User Controls to Implement Master/Details Scenarios
    7. Part 7: Using Templates to Customize Control Look and Feel
    8. Part 8: Creating a Digg Desktop Version of our Application using WPF

    I'll be able to tell you more about the WCF subset once the beta actually comes out.

  • Nicholas Allen's Indigo Blog

    Using Call Context Initializers for Culture

    • 2 Comments

    Let's build on a few earlier samples to actually demonstrate a working call context initializer. I'll start with yesterday's skeleton for a call context initializer and behavior. To that skeleton I'll add implementations of BeforeInvoke and AfterInvoke that initialize the operation thread with custom culture information and then clean the thread up once the operation return.

    class CultureInitializer : ICallContextInitializer
    {
    CultureInfo newInfo;

    public CultureInitializer(CultureInfo newInfo)
    {
    this.newInfo = newInfo;
    }

    public void AfterInvoke(object correlationState)
    {
    Thread.CurrentThread.CurrentCulture = correlationState as CultureInfo;
    }

    public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
    {
    CultureInfo oldInfo = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = newInfo;
    return oldInfo;
    }
    }

    Then, I'll fill out ApplyDispatchBehavior to apply my call context initializer to every operation on the given endpoint.

    class CultureInitializerBehavior : IEndpointBehavior
    {
    CultureInfo newInfo;

    public CultureInitializerBehavior(CultureInfo newInfo)
    {
    this.newInfo = newInfo;
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations)
    {
    operation.CallContextInitializers.Add(new CultureInitializer(newInfo));
    }
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
    }

    Finally, I'll take last week's custom fault encoding sample and install my behavior. Notice that the only change at the service level is to add the behavior to the endpoint behavior collection. If I had written the code to apply the behavior in an attribute or configuration file, either of those approaches would have worked as well.

    [ServiceContract]
    public interface IMyService
    {
    [OperationContract]
    Message Fail();
    }

    public class MyService : IMyService
    {
    public Message Fail()
    {
    XmlDocument document = new XmlDocument();
    document.LoadXml("<tag attributeName=\"value\"><moretags>blah</moretags></tag>");
    throw new FaultException<XmlElement>(document.FirstChild as XmlElement);
    }
    }

    public class Program
    {
    static void Main(string[] args)
    {
    string address = "http://localhost:8000/";
    BasicHttpBinding binding = new BasicHttpBinding();
    ServiceHost host = new ServiceHost(typeof(MyService), new Uri(address));
    ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IMyService), binding, "");
    endpoint.Behaviors.Add(new CultureInitializerBehavior(new CultureInfo("en-GB")));
    host.Open();
    ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding);
    IMyService proxy = factory.CreateChannel(new EndpointAddress(address));
    Message response = proxy.Fail();
    Console.WriteLine(response.ToString());
    Console.ReadLine();
    host.Close();
    }
    }

    Now when I run the full sample notice that the xml:lang changes in the fault reason because the fault reason is a localizable field and based by default on the current culture.

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header />
    <s:Body>
    <s:Fault>
    <faultcode>s:Client</faultcode>
    <faultstring xml:lang="en-GB">The creator of this fault did not specify a Reason.</faultstring>
    <detail>
    <tag attributeName="value">
    <moretags>blah</moretags>
    </tag>
    </detail>
    </s:Fault>
    </s:Body>
    </s:Envelope>

    Next time: Runtime Limits in IIS

  • Nicholas Allen's Indigo Blog

    Using Call Context Initializers for Cleanup

    • 2 Comments

    I'm using framework features that have thread-local settings. These settings then get leaked to other client calls. How can I stop this from happening?

    The problem here is that WCF doesn't know about these thread-local setting changes that you've made and so doesn't know that they need to be cleaned up. WCF by default is more frugal than other stacks, such as ASP.NET, when it comes to protecting state. Saving and restoring lots of thread-local settings takes time regardless of whether you actually did something with those settings or not. WCF tries not to do as much on your behalf so that you don't have to pay for cleanup unless you're using those features. It does however give you the hooks necessary to arrange for this cleanup to take place at the appropriate time.

    The ICallContextInitializer interface lets you hook the beginning and end of operation calls. Hooking the end of the call allows you to cleanup these setting changes. It's easiest to insert an ICallContextInitializer by applying an endpoint behavior to your application endpoints.

    class MyInitializer : ICallContextInitializer
    {
    public void AfterInvoke(object correlationState)
    {
    // Clean up thread-local settings here
    }

    public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
    {
    return null;
    }
    }

    class MyInitializerBehavior : IEndpointBehavior
    {
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    // Add instances of your call context initializer to the CallContextInitializers collection
    // of the appropriate operations located at endpointDispatcher.DispatchRuntime.Operations.
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
    }

    Next time we'll look at a more complete example of using ICallContextInitializer to solve a problem with setting up thread-local settings as well.

    Next time: Using Call Context Initializers for Culture

  • Nicholas Allen's Indigo Blog

    DataMember Best Practices

    • 3 Comments

    I was asked to share a list of best practices I wrote for data contracts and data members so here it is:

    1. Do apply the DataMember attribute only to properties rather than the corresponding fields.
    2. Do not use type inheritance to version a data contract. Either modify the existing type or create an entirely new type.
    3. Do not add or remove enumeration members between versions.
    4. Do not change the name or namespace of a data contract or data members between versions.
    5. Do not change the order of data members between versions.
    6. Do set the IsRequired property to false on data members added in later versions.
    7. Do not remove data members in later versions even if they are marked as not required.
    8. Do support IExtensibleDataObject on data contracts to support future compatibility with extended types.
    9. Do apply the DataMember attribute only to public members. Serialization of private data members is not supported for partial trust environments.
    10. Do not rely on constructor visibility, constructor link demands, constructor security actions, or validation checks in the constructor to make a DataContract type safe for partially trusted callers. DataContractSerializer does not invoke the constructor when initializing an object.

    Next time: Using Call Context Initializers for Cleanup

  • Nicholas Allen's Indigo Blog

    Getting Started with WCF and WF in VB

    • 1 Comments

    Many of the concepts in WCF and WF are language independent but it's hard to get a practical description of building services and workflows without making some assumptions about programming languages and tools. Much of the product documentation is available for both C# and VB developers. However, the typical article writer only provides examples using the predominant language for the product. I present everything using C# but I know that there are a large number of developers out there using Visual Basic. Recently I noticed that the Visual Basic MVPs had contributed some articles about WCF and WF to MSDN.

    I've been seeing more articles and books lately that include VB as either a primary or alternate language when covering WCF and WF topics. I encourage these kinds of efforts to make content more broadly available.

  • Nicholas Allen's Indigo Blog

    Embedding Arbitrary XML in Faults

    • 2 Comments

    How can I directly craft the XML content that goes into a fault detail?

    Getting control over the detail element doesn't have to mean crafting the fault message yourself. While WCF requires that the fault detail be serializable using a data contract, remember that DataContractSerializer treats XmlElement as a special primitive type. This allows you to construct arbitrary content using XmlElement when your content can be represented as a rooted document. Due to the automatic conversion process of FaultException to a fault message, you don't need to construct a data contract to act as a wrapper.

    Here's a sample that builds some content in an XmlElement and uses it to construct a fault. I made the method return a Message so that I could look at the response more easily but you can use any contract you want.

    [ServiceContract]
    public interface IMyService
    {
    [OperationContract]
    Message Fail();
    }

    public class MyService : IMyService
    {
    public Message Fail()
    {
    XmlDocument document = new XmlDocument();
    XmlElement root = document.CreateElement("tag");
    root.SetAttribute("attributeName", "value");
    XmlElement subtag = document.CreateElement("moretags");
    subtag.InnerText = "blah";
    root.AppendChild(subtag);
    throw new FaultException<XmlElement>(root);
    }
    }

    public class Program
    {
    static void Main(string[] args)
    {
    string address = "http://localhost:8000/";
    BasicHttpBinding binding = new BasicHttpBinding();
    ServiceHost host = new ServiceHost(typeof(MyService), new Uri(address));
    host.AddServiceEndpoint(typeof(IMyService), binding, "");
    host.Open();
    ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding);
    IMyService proxy = factory.CreateChannel(new EndpointAddress(address));
    Message response = proxy.Fail();
    Console.WriteLine(response.ToString());
    Console.ReadLine();
    host.Close();
    }
    }

    That code produces a fault message that looks like the following.

    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header />
    <s:Body>
    <s:Fault>
    <faultcode>s:Client</faultcode>
    <faultstring xml:lang="en-US">The creator of this fault did not specify a Reason.</faultstring>
    <detail>
    <tag attributeName="value">
    <moretags>blah</moretags>
    </tag>
    </detail>
    </s:Fault>
    </s:Body>
    </s:Envelope>

    Depending on how much hand-crafting you want, XmlDocument lets you simplify the process even further. For example, you could generate the same message from simple XML completely put together by hand.

    XmlDocument document = new XmlDocument();
    document.LoadXml("<tag attributeName=\"value\"><moretags>blah</moretags></tag>");
    throw new FaultException<XmlElement>(document.FirstChild as XmlElement);

    Next time: DataMember Best Practices

  • Nicholas Allen's Indigo Blog

    WCF Content at MIX

    • 0 Comments

    If you're planning to attend MIX next month with an interest in WCF, look for these sessions in particular:

    • Creating a RESTful API with Windows Communication Foundation
      Speaker(s): Viphak Lay, Haider Sabri, Paul Walker

      Learn how MySpace used Windows Communication Foundation and .NET 3.5 to rapidly scale up a massive RESTful API infrastructure that process millions of requests a day.

    • Working with Data and Web Services in Microsoft Silverlight 2
      Speaker(s): Eugene Osovetsky

      Learn how easy it is to utilize POX, REST, RSS, ATOM, JSON, and SOAP in your Microsoft Silverlight mashup applications. Also learn how to easily access and display data with Silverlight using LINQ and databinding.

    • Building Applications and Services with .NET Framework 3.5
      Speaker(s): Justin Smith

      Come see how the new Web-friendly features in .NET 3.5 Windows Communication Foundation extend the reach of your services to simple clients like Web browsers and RSS aggregators.

    • Using an Internet Service Bus to Build Next Generation Applications and Services
      Speaker(s): Dennis Pilarinos

      Learn how using Microsoft's Internet Service Bus technologies including pub/sub, message transformation, and hosted workflow enables you to easily and quickly build complex applications and services that require reach, scale, and access control.

    You may also be interested in these sessions which cover web service and related development but aren't focused on WCF:

    • Building Rich Internet Applications Using Microsoft Silverlight 2, Part 1
      Speaker(s): Mike Harsh, Joe Stegman

      Learn how to use Microsoft Visual Studio to create applications, how to create UI using XAML markup and code, how to build a custom control, how to retrieve data from a Web service, and how to manipulate data with XML and LINQ. (Part 1 of 2)

    • Building Rich Internet Applications Using Microsoft Silverlight 2, Part 2
      Speaker(s): Mike Harsh, Joe Stegman

      Learn how to use Microsoft Visual Studio to create applications, how to create UI using XAML markup and code, how to build a custom control, how to retrieve data from a Web service, and how to manipulate data with XML and LINQ. (Part 2 of 2)

    • Building RESTful Real World Applications with the ADO.NET Data Services Framework
      Speaker(s): Mike Flasko

      Come hear from developers creating real-world applications and user-interface controls on top of the ADO.NET Data Services Framework (aka Project "Astoria"). Learn best practices for building RESTful applications and components,.

    • RESTful Data Services with the ADO.NET Data Services Framework
      Speaker(s): Pablo Castro

      Learn how to use ADO.NET Data Services Framework to easily create and consume REST data services on the web. This session will cover the main concepts of the ADO.NET Data Services Framework (aka Project "Astoria"), show how to use it, and discuss how to use it with Microsoft's broader vision of a common interface for Windows Live and 3rd party services.

  • Nicholas Allen's Indigo Blog

    Scopes of Encryption

    • 1 Comments

    This article is primarily an introduction on protecting message data since the topic overall seems to cause some confusion. The source of confusion is what it means for a service to define a contract for protecting data. Data protection flows from two different directions and at a variety of different scopes.

    The service can define a minimum standard of protection at various contract scopes.

    • Service contracts cover all of the application data exchanged by the service
    • Operation contracts cover all of the application data exchanged for that particular operation
    • Message and fault contracts cover all of the application data contained in those particular messages
    • Message body and message header contracts cover those particular parts of the message

    This minimum standard appears as the ProtectionLevel on a contract and comes in three flavors: no protection, protected by digital signing, and protected by encryption (the use of encryption implies a signature as well). Signing prevents people from tampering with the messages while encryption prevents people from reading the messages.

    These contracts define the application messages that are exchanged. Depending on the protocols you make use of, any number of infrastructure headers or messages may need to be inserted into the data stream to facilitate the exchange of your application messages. This infrastructure data can have its own independent rules for protection.

    The ProtectionLevel truly is a minimum standard. It is ok for your application to receive messages that are protected better than the minimum standard defines. You may even send messages that are protected better than the minimum standard due to the other direction for flowing data protection. Data can be protected at the wire level by using security integrated with the network transport. For example, if you send data using HTTPS, then there is a level of protection that HTTPS must apply to your messages to transport them even if your contract specified a lower standard.

    The net protection level is the maximum of that provided by the service and provided by the transport. As long as for every piece of data at every scope that maximum is greater than your minimum standard, then everything works. If that maximum fails to meet your minimum standard, then the service will refuse to send or receive those messages.

    Next time: Embedding Arbitrary XML in Faults

  • Nicholas Allen's Indigo Blog

    Augmenting Security Requests

    • 1 Comments

    How can I add some additional information to the request when contacting a token server?

    Looking at the schema for a RequestSecurityToken message, there clearly is some extensibility space intended for providing additional information in the request. We'll ignore the fact that the actual schema says that the whole thing is an xs:any and only look at the annotated content model because WCF is a lot more likely to be designed with that content model in mind.

    <xs:element name='RequestSecurityToken' type='wst:RequestSecurityTokenType' />
    <xs:complexType name='RequestSecurityTokenType' >
    <xs:annotation>
    <xs:documentation>
    Actual content model is non-deterministic, hence wildcard. The following shows intended content model:

    &lt;xs:element ref='wst:TokenType' minOccurs='0' />
    &lt;xs:element ref='wst:RequestType' />
    &lt;xs:element ref='wsp:AppliesTo' minOccurs='0' />
    &lt;xs:element ref='wst:Claims' minOccurs='0' />
    &lt;xs:element ref='wst:Entropy' minOccurs='0' />
    &lt;xs:element ref='wst:Lifetime' minOccurs='0' />
    &lt;xs:element ref='wst:AllowPostdating' minOccurs='0' />
    &lt;xs:element ref='wst:Renewing' minOccurs='0' />
    &lt;xs:element ref='wst:OnBehalfOf' minOccurs='0' />
    &lt;xs:element ref='wst:Issuer' minOccurs='0' />
    &lt;xs:element ref='wst:AuthenticationType' minOccurs='0' />
    &lt;xs:element ref='wst:KeyType' minOccurs='0' />
    &lt;xs:element ref='wst:KeySize' minOccurs='0' />
    &lt;xs:element ref='wst:SignatureAlgorithm' minOccurs='0' />
    &lt;xs:element ref='wst:Encryption' minOccurs='0' />
    &lt;xs:element ref='wst:EncryptionAlgorithm' minOccurs='0' />
    &lt;xs:element ref='wst:CanonicalizationAlgorithm' minOccurs='0' />
    &lt;xs:element ref='wst:ProofEncryption' minOccurs='0' />
    &lt;xs:element ref='wst:UseKey' minOccurs='0' />
    &lt;xs:element ref='wst:SignWith' minOccurs='0' />
    &lt;xs:element ref='wst:EncryptWith' minOccurs='0' />
    &lt;xs:element ref='wst:DelegateTo' minOccurs='0' />
    &lt;xs:element ref='wst:Forwardable' minOccurs='0' />
    &lt;xs:element ref='wst:Delegatable' minOccurs='0' />
    &lt;xs:element ref='wsp:Policy' minOccurs='0' />
    &lt;xs:element ref='wsp:PolicyReference' minOccurs='0' />
    &lt;xs:any namespace='##other' processContents='lax' minOccurs='0' maxOccurs='unbounded' />

    </xs:documentation>
    </xs:annotation>
    <xs:sequence>
    <xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' />
    </xs:sequence>
    <xs:attribute name='Context' type='xs:anyURI' use='optional' />
    <xs:anyAttribute namespace='##other' processContents='lax' />
    </xs:complexType>

    Now the question is how to take advantage of that extensibility in the easiest way. By tracing backwards from the point where a RequestSecurityToken is written out, I arrive at finding that the first publicly accessible field controlling that content is IssuedSecurityTokenParameters.AdditionalRequestParameters. AdditionalRequestParameters is just a collection over XmlElement so that clearly lets me put anything I want in there. However, where would an IssuedSecurityTokenParameters get created? Tracing a little bit farther back reveals that a WSFederationHttpBinding creates an IssuedSecurityTokenParameters as part of building the security binding element. The content that gets put into the AdditionalRequestParameters is the TokenRequestParameters from the binding's message security settings. Therefore, we can add some additional information to the request when contacting a token server by writing code that looks like this:

    WSFederationHttpBinding binding = new WSFederationHttpBinding();
    binding.Security.Message.TokenRequestParameters.Add( ... );

    Next time: Scopes of Encryption

  • Nicholas Allen's Indigo Blog

    DinnerNow 2008

    • 0 Comments

    DinnerNow is a sample restaurant marketplace application that demonstrates many different Microsoft web service technologies. You may have seen the application distributed as a standalone sample as well as appearing in many hands-on labs and booth demos for Microsoft developer conferences. If you've taken a look at DinnerNow in the past, then you might want to check out the new DinnerNow 2.5 release that's been updated for Orcas and Visual Studio 2008. In addition to the new platforms, there are several new features being demonstrated as well:

    • Integration between WCF and WF in Orcas
    • WCF Orcas Syndication API
    • Hosting WCF services in IIS7
    • WCF on the .NET Compact Framework 3.5
    • LINQ to SQL
  • Nicholas Allen's Indigo Blog

    Differences in Enum Serialization

    • 2 Comments

    Why does adding an enum parameter to an operation cause the proxy to explode into message contracts?

    This was a question asking why the following perfectly ordinary operation contract caused svcutil.exe to spit out some really ugly code.

    [OperationContract]
    void Foo(EnumType e);

    Getting started debugging the problem was fairly easy because svcutil left a nice comment explaining what went wrong during code generation.

    // CODEGEN: Generating message contract since element name e from namespace http://tempuri.org/ is not marked nillable
    

    This was a completely accurate statement because when I checked the schema for the operation, the operation parameter was not marked nillable. However, it didn't help at all to explain why this was happening.

    <xs:element name="Foo">
    <xs:complexType>
    <xs:sequence>
    <xs:element xmlns:q1="http://schemas.datacontract.org/2004/07/" minOccurs="0" name="e" type="q1:EnumType" />
    </xs:sequence>
    </xs:complexType>
    </xs:element>

    A brutal way to solve the problem would be to change the operation parameter from EnumType to EnumType? to force it to be nillable. Clearly though, something more fundamental was wrong because when I checked the schema for EnumType it was not what I expected.

    <xs:simpleType name="EnumType">
    <xs:restriction base="xs:string" />
    </xs:simpleType>

    The error wasn't that EnumType was passed as a string (it's relatively common to represent an enumeration using the names of the values), but that the type didn't actually define any values at all. I would have expected to see under the restriction a list of enumeration values for this type. This was also apparent in the generated proxy. The proxy was using raw strings rather than a nice enumerated type because the restriction had no values defined.

    The problem was solved by looking at the definition of EnumType.

    [DataContract]
    public enum EnumType { ValueOne, ValueTwo }

    By applying a DataContract attribute, the default serialization contract for the enum was replaced by a contract that didn't include any of the values as members. The default contract would have included all of the values. Specifying a DataContract attribute is only needed when customizing the serialization contract, such as when you only want to expose a subset of the enumeration values. Removing the spurious DataContract attribute fixed the schema problems and allowed svcutil to generate proxies with a nice enumeration type.

    Next time: Augmenting Security Requests

  • Nicholas Allen's Indigo Blog

    10 Years of XML and More Still Coming

    • 1 Comments

    Over the weekend XML 1.0 turned 10 years old from the day it was first accepted as a W3C recommendation. It started as a subset of SGML that allowed generic document content to be served and processed over HTTP. It's now used for everything, including the kitchen sink.

    XML 1.0 included a number of quirks, such as a large and complicated language production that created a custom subset of Unicode for defining names. XML 1.1 tried to fix these quirks but broke compatibility in the process, leading to its virtual death due to lack of adoption. The world still works off of XML 1.0. That's why last week a new proposed recommendation came out to define a Fifth Edition of XML 1.0.

  • Nicholas Allen's Indigo Blog

    Windows Server 2008 (and Orcas) SDK Released

    • 0 Comments

    Last week the final version of the Windows Server 2008 SDK went online. If you've been using the beta SDK releases for Orcas samples or tools, then this is the version of the SDK that you'll want to install. Here are the links to the download materials:

    I don't have any particular known issues to call out for WCF other than that some of the SDK tools require that you have Orcas installed. If you're developing Windows Server 2008 applications but don't want to upgrade to Orcas, then you can grab the appropriate tools from one of the previous Windows Vista SDK releases.

  • Nicholas Allen's Indigo Blog

    Producing Typed Messages

    • 3 Comments

    How do typed messages get created from an object that has a message contract?

    There seem to be a lot of examples that talk about how messages get produced when they're described by data contracts but relatively few descriptions of the equivalent process for message contracts. There's really nothing complicated or magical here so let's go through it.

    I'll start with a message that I want to describe with a message contract and then build the contract class.

    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
    <s:Header>
    <h:version xmlns:h="http://mycorp.com">1</h:version>
    </s:Header>
    <s:Body>
    <name xmlns="http://mycorp.com">Microsoft</name>
    <address xmlns="http://mycorp.com">1 Microsoft Way</address>
    </s:Body>
    </s:Envelope>

    There's a message header whose type is an integer and two body members whose types are strings. This is a pretty easy message to describe although I have to change the settings for the wrapper and namespaces to get the structure to match. I apply an order to the body members because the default would reverse them.

    [MessageContract(IsWrapped=false)]
    class MyMessage
    {
    [MessageHeader(Namespace = "http://mycorp.com")]
    public int version { get; set; }

    [MessageBodyMember(Namespace = "http://mycorp.com", Order = 1)]
    public string name { get; set; }

    [MessageBodyMember(Namespace = "http://mycorp.com", Order = 2)]
    public string address { get; set; }
    }

    Now I can use the TypedMessageConverter class to go between the message contract and a Message object.

    MyMessage record = new MyMessage();
    record.version = 1;
    record.name = "Microsoft";
    record.address = "1 Microsoft Way";
    TypedMessageConverter converter = TypedMessageConverter.Create(typeof(MyMessage), null);
    Message message = converter.ToMessage(record, MessageVersion.Soap12);
    Console.WriteLine(message.ToString());

    message.Headers.Clear();
    message.Headers.Add(MessageHeader.CreateHeader("version", "http://mycorp.com", 2));
    MyMessage record2 = (MyMessage)converter.FromMessage(message);
    Console.WriteLine(record2.version);
    Console.WriteLine(record2.name);
    Console.WriteLine(record2.address);

    I changed the version header for the return trip just to prove that there's no cheating going on. I gave an explicit message version when creating the message because otherwise I would have gotten SOAP 1.2 with WS-Addressing 1.0. My sample message didn't have any addressing information so I wanted to avoid potentially introducing some. TypedMessageConverter uses a factory pattern and doesn't promise anything about the default message version so I would never rely on the default behavior even if it seemed to match what I wanted.

    Next time: Differences in Enum Serialization

  • Nicholas Allen's Indigo Blog

    New Toy MSDeploy

    • 1 Comments

    The IIS team has released a preview version of a new tool for synchronizing, migrating, and deploying web sites hosted in IIS. This looks like something that could turn into a real time saver and prevent some pretty nasty headaches with IIS configuration in the future. Here are the downloads:

    You can get more information on the new web deployment team blog.

  • Nicholas Allen's Indigo Blog

    Scott Guthrie Talks MIX

    • 0 Comments

    Channel 9 has a new video interview with Scott Guthrie talking about IIS, MIX, Silverlight 2.0, and other topics. The interview is split into two parts although it's really the same conversation.

    1. Scott Guthrie: What's Coming for Mix, Part 1: IIS7 for Developers
    2. Scott Guthrie: What's Coming for Mix, Part 2: Windows, Web, and RIA

    The first part is about 15 minutes while the second part is about 45 minutes.

    The topics are mixed up throughout the interview but Part 1 and the first 15 minutes of Part 2 are mostly about IIS while the rest of Part 2 is mostly about MIX and Silverlight.

    For more information about MIX, visit the MIX 2008 website.

  • Nicholas Allen's Indigo Blog

    Building on Custom Cookie Handling

    • 2 Comments

    By request I expanded the code in the earlier article on custom cookie handling to show a more interesting sample. This time I illustrated making the initial request and capturing a cookie rather than echoing a cookie that the client already had. This sample is specifically written to not use proxies or any of the web programming features so that you can see exactly what goes on under the covers. I threw in a demonstration of CookieContainer for integration but you can use any mechanism you'd like to manage the cookies.

    You can run this code against your favorite site that distributes cookies. I picked a random site that advertised having a cookie tester. There's no guarantee that this site will be there tomorrow.

    using System;
    using System.Net;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Text;

    class CookieTest
    {
    static void Main(string[] args)
    {
    string address = "http://www.tempesttech.com/cookies/cookietest1.asp";
    Binding binding = new CustomBinding(
    new TextMessageEncodingBindingElement(MessageVersion.None, Encoding.UTF8),
    new HttpTransportBindingElement()
    );
    IChannelFactory<IRequestChannel> factory = binding.BuildChannelFactory<IRequestChannel>();
    IRequestChannel channel = null;
    bool success = false;
    try
    {
    factory.Open();
    channel = factory.CreateChannel(new EndpointAddress(address));
    channel.Open();
    Message request = Message.CreateMessage(MessageVersion.None, null);
    HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
    requestProperty.Method = "GET";
    requestProperty.SuppressEntityBody = true;
    request.Properties[HttpRequestMessageProperty.Name] = requestProperty;
    Message response = channel.Request(request);
    request.Close();
    HttpResponseMessageProperty responseProperty =
    response.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
    CookieContainer container = new CookieContainer();
    container.SetCookies(new Uri(address), responseProperty.Headers[HttpResponseHeader.SetCookie]);
    response.Close();
    foreach (Cookie cookie in container.GetCookies(new Uri(address)))
    {
    Console.WriteLine(cookie);
    }
    channel.Close();
    factory.Close();
    success = true;
    }
    catch (TimeoutException e)
    {
    Console.WriteLine(e);
    }
    catch (CommunicationException e)
    {
    Console.WriteLine(e);
    }
    finally
    {
    if (!success)
    {
    if (channel != null)
    {
    channel.Abort();
    }
    factory.Abort();
    }
    }
    Console.ReadLine();
    }
    }

    Next time: Producing Typed Messages

  • Nicholas Allen's Indigo Blog

    TCP Throttling

    • 1 Comments

    As I mentioned on the 30th anniversary of IP, an early and fundamental split was made in TCP to distinguish point-to-point messaging from end-to-end messaging. The split is based on a philosophy that the communication endpoints should be in control and that there should be a minimal amount of functionality and responsibility distributed along the communication path in between.

    The end-to-end philosophy shows up in how TCP systems perform throttling. Duplication of throttling makes the system more complicated. Duplication of throttling also makes the system less efficient because more throttling decisions have to be made by intermediaries that have less information about the system than the endpoints. TCP uses flow control to establish how fast data can be transmitted from the sender to the receiver. Rather than having the communication path adjust the flow rate, TCP uses congestion control algorithms to infer how the sender should change its transmission strategy to best use the network.

    In the basic implementation of TCP, the data stream is overlaid by a transmission window that defines which packets can be sent. As packets are received and acknowledged, the transmission window slides along the data stream. The endpoints grow and shrink the size of the transmission window as needed to adjust the flow rate. Initially the transmission window is very small because the state of the communication path is unknown. However, the window size adapts itself over time to an optimal rate of transmission. Some of the changes to the TCP/IP stack in Windows Vista were to accelerate the rate of adaptation and reduce the amount of time spent using a sub-optimal transmission rate.

    The end-to-end philosophy also shows up in how the WCF TCP channel avoids trying to do throttling. The service knows more about how it's going to use the network than the networking stack does. Consequently, if you want to control how quickly things are sent and received, the best place to control that is in the application. The only bottleneck in the TCP channel is how quickly it can pass information back and forth between the application and the wire. The default quota settings for the channel are sufficient for networks up to 100 Mbps. You'll want to increase the ConnectionBufferSize quota from its default of 8 KB to something like 64 KB on faster networks.

    Note that if the throttling is desired for fairness between applications rather than within an application, then the best place to do the throttling is outside of the applications. Again, this follows the principle that the decision should be made where there's the most information.

    Next time: Building on Custom Cookie Handling

  • Nicholas Allen's Indigo Blog

    Programming for the Web in Orcas

    • 1 Comments

    Steve Maine has put together an index of documentation for all of the new WCF web programming features in Orcas. This includes the support for:

    • JSON
    • RSS and Atom syndication feeds
    • URI templates
    • HTTP enhancements

    As well as features that web developers tend to care about more than average, such as partial trust hosting.

Page 1 of 1 (21 items)