November 2010 - Posts

As I discussed in my last post, the new WCF Http Model includes http processors that you can use to inject cross cutting aspects into an existing service. We can use processors for supporting a versioning schema based on content types as it discussed here by Peter Williams. 

Supporting custom media types in a WCF Http Service is a now a piece of cake with the new MediaTypeProcessor. The only thing you need to do is to implement a new processor by deriving your  class from the base class MediaTypeProcessor or any existing implementation like XmlProcessor for example.

The implementation I showed below derives from the XmlProcessor implementation and adds support for two new content types (“application/vnd.mycompany.myapp+xml” and “application/vnd.mycompany.myapp-v2+xml”)

public class XmlVersionedProcessor : XmlProcessor
{
    public static readonly MediaTypeVersion[] Versions = new MediaTypeVersion[] 
    {
        new MediaTypeVersion { Version = 1, MediaType = "application/vnd.mycompany.myapp+xml" },
        new MediaTypeVersion { Version = 2, MediaType = "application/vnd.mycompany.myapp-v2+xml" },
    };
 
    public XmlVersionedProcessor(HttpOperationDescription operation, MediaTypeProcessorMode mode)
        : base(operation, mode)
    {
    }
 
    public override IEnumerable<string> SupportedMediaTypes
    {
        get
        {
            foreach (var mediaType in base.SupportedMediaTypes)
            {
                yield return mediaType;
            }
 
            foreach (var mediaType in Versions.Select(v => v.MediaType))
            {
                yield return mediaType;
            }
        }
    }
 
    public class MediaTypeVersion
    {
        public int Version { get; set; }
        public string MediaType { get; set; }
    }
}

That represents one part of the implementation. Now, the resource implementation somehow needs to know which message it needs to return according to the “accept” header sent by the client implementation. The resource implementation can just look for the “accept” header in the request message by passing an “HttpRequestMessage” argument to the operation. However, I decided to go with a different approach so the operation implementation did not get tied to a content type.

[ServiceContract]
public class AccountResource
{
    [OperationContract]
    [WebGet(UriTemplate = "{id}")]
    public Account Get(string id, int version)
    {
        if (version == 1)
        {
            return new Account { Name = id };
        }
        else 
        {
            return new AccountV2 { Name = id, Email = new string[] { id + "@mail.com" } };
        }
    }
}

The operation receives an argument representing the version that needs to be returned to the client. As you can see, the implementation returns Account or AccountV2 based on that version argument.

[XmlInclude(typeof(AccountV2))]
public class Account
{
    public string Name { get; set; }
}
    
public class AccountV2 : Account
{
    public string[] Email { get; set; }
}

AccountV2 adds a list of emails to the account information.

You might be asking how I did to transform the accept header into a version argument. Well, the response is another processor implementation :)

public class VersionProcessor : Processor<RequestHeaders, int>
{
    public VersionProcessor()
    {
        this.InArguments[0].Name = HttpPipelineFormatter.ArgumentRequestHeaders;
        this.OutArguments[0].Name = "version";
    }
 
    public override ProcessorResult<int> OnExecute(RequestHeaders input)
    {
        foreach (var accept in input.Accept)
        {
            var version = XmlVersionedProcessor
                .Versions.FirstOrDefault(v => v.MediaType.Equals(accept.Value, 
                    StringComparison.InvariantCultureIgnoreCase));
 
            if (version != null)
            {
                return new ProcessorResult<int>
                {
                    Output = version.Version
                };
            }
        }
 
        return new ProcessorResult<int>    { Output = 0 };
    }
}

This processor receives the RequestHeaders, looks for the Accept Header in the “OnExecute” method, and returns a version number based on the value found on that header. The version number in this example could be 1 for “application/vnd.mycompany.myapp+xml” or 2 for “application/vnd.mycompany.myapp-v2+xml”.

Posted by cibrax | 2 comment(s)
Filed under: , ,

The code drop recently released as part of wcf.codeplex.com introduced a new feature for injecting cross-cutting concerns through a pipeline into any existing service. The idea is simple, when you move to the http world, there are some aspects that might want to move out of your operation implementation. A typical example is content negotiation, in which the http messages are serialized or deserialized into specific entity or object graph expected by the service based on the “content-type” or “accept” http headers.  You don’t want to have all that logic spread across all the service implementations or tie your operation to an specific format as it happened with previous model with the WebInvoke and WebGet attributes. For that kind of logic, it’s really useful to have that concern implemented in a specific class that you can test individually and inject into your service to support new message formats.

From a high level, if you look at how the WCF service model works, this new pipeline runs just after the operation has been selected and right after the operation has been executed, meaning that you have two pipeline instances, one for request messages and another one for the responses.

The image above illustrates the service model architecture, and the pipelines are implemented in the message formatting stage.

processors_architecture

The pipeline is a collection a processors or handlers that perform a transformation task. A simple processor receives a set of input arguments and returns some output arguments. The nice thing about how the processors and pipeline are implemented in this new model is that you can chain the output results from a processor into another processor as input arguments.

The following image shows how the pipeline works at first glance.

processors_pipeline

The first processor in the pipeline injects some output values into the context (A and B), and that context is then passed to the successive processors until the service operation is finally executed. The arguments that the operation is expecting  are also be resolved from the available values in the pipeline context.

The UriTemplateProcessor is a built-in processor implementation that WCF always inject by default in the request pipeline to transform the values passed as uri templates to the http resource (or service) as output arguments that other processors can reuse as input. For example, if you have an UriTemplate with a variable argument “culture” as part of your operation definition like this one,

[WebGet(UriTemplate="{culture}")]

And you pass a value for that template in the URL,

http://localhost/helloworld/en-us (being en-us the {culture} template in the url)

The UriTemplateProcessor will catch the “en-us” value and add it to the pipeline context as “culture”.

For other processors that you can implement on your own, you can either derive your implementation from the base class “System.ServiceModel.Dispatcher.Processor” or one of the existing definitions that use generic templates for the input and output arguments.

public abstract class Processor<T, TOutput> : Processor
public abstract class Processor<T1, T2, TOutput> : Processor
public abstract class Processor<T1, T2, T3, TOutput> : Processor
......
public abstract class Processor<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TOutput> : Processor

The main difference with these class definitions is that you can specify a type for the input or output arguments that the processor can handle. When you implement a processor, in addition to specify the types the processor might expect for the input or output arguments, you also need to give names to those arguments so the pipeline knows how to map the values for those arguments from the existing context.

In the given example with the “culture” argument, and assuming that UriTemplateProcessor has already run and added the value for that argument into the pipeline context, a pipeline processor can get access to that value by naming an input argument with the same name.

public class CultureProcessor : Processor<string, CultureInfo>
{
    public CultureProcessor()
        : base()
    {
        this.InArguments[0].Name = "culture";
        this.OutArguments[0].Name = "culture";
    }

The example above receives an input argument culture as string, and returns an output argument with the same name as an instance of the CultureInfo. Either the service or any other processor in the chain will able to receive now an instance of CultureInfo if they expect an argument with a name “culture”.

A processor can also receive an instance of the object representing the request (HttpRequestMessage) or response messages (HttpResponseMessage), which are the two new message primitive classes added in this release for giving better access to developers to the http context. You can receive either of these messaging classes by naming the arguments HttpPipelineFormatter.ArgumentHttpRequestMessage (HttpRequestMessage) or HttpPipelineFormatter.ArgumentHttpResponseMessage (HttpResponseMessage) respectively.

As we have discussed so far, a processor runs late in the WCF pipeline and there much after the Http transport channels have done their job. For that reason, it would not make much sense to implement Http transport concerns like security in a processor.

The framework also ships with a processor implementation for handling content negotiation “Microsoft.ServiceModel.Http.MediaTypeProcessor”, which provides several abstraction methods that you can override for participating in the process. 

public abstract class MediaTypeProcessor : Processor
{
    public abstract IEnumerable<string> SupportedMediaTypes { get; }
 
    public abstract void WriteToStream(object instance, Stream stream, HttpRequestMessage request);
 
    public abstract object ReadFromStream(Stream stream, HttpRequestMessage request);
}

The names for these method pretty much say everything. You have a method “SupportedMediaTypes” for specifying the supported content types that your implementation can handle (for example text/xml or text/html), and two methods for serializing and deserializing an object instance representing the request body or response body into one of the supported media types. Some implementations come with the framework the handling the most common media types like XmlProcessor, HtmlProcessor, JsonProcessor, PlainTextProcessor or FormUrlEncodedProcessor.

You are also free to implement your own media type processors to support custom media types that makes sense for your services. A typical example is when you want to support media types “+xml” or “+json” in your services like “application/x-order-process+xml” or “ application/x-order-process+json” for example or support a versioning schema based on custom media types as it is discussed here, http://barelyenough.org/blog/2008/05/versioning-rest-web-services/ 

Finally, the processors are injected into any existing service using a concrete implementation of “Microsoft.ServiceModel.Http.HostConfiguration” class, which is usually wired up with host initialization.

public class ContactManagerConfiguration : HostConfiguration
{
    public override void RegisterRequestProcessorsForOperation(HttpOperationDescription operation, IList<Processor> processors, MediaTypeProcessorMode mode)
    {
        if(operation.Name == "Get" && operation.DeclaringContract.Name == "ContactResource")
            processors.Add(new CultureProcessor());
 
        processors.Add(new JsonProcessor(operation, mode));
        processors.Add(new FormUrlEncodedProcessor(operation, mode));
    }
 
    public override void RegisterResponseProcessorsForOperation(HttpOperationDescription operation, IList<Processor> processors, MediaTypeProcessorMode mode)
    {
        processors.Add(new JsonProcessor(operation, mode));
        processors.Add(new PngProcessor(operation, mode));
    }
}

Two abstract methods are provided with that class, one for registering the processors for the request pipeline, and another one for the response pipeline respectively. The example below passes this custom configuration as part of the routing configuration for a service hosted in ASP.NET,

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        var configuration = new ContactManagerConfiguration();
        RouteTable.Routes.AddServiceRoute<ContactResource>("contact/", configuration);
        RouteTable.Routes.AddServiceRoute<ContactsResource>("contacts", configuration);
        RouteTable.Routes.AddServiceRoute<HelloWorldResource>("hello", configuration);
    }
}
Posted by cibrax | 3 comment(s)
Filed under: , ,

As part of the simplification in service configuration that we want to provide in SO-Aware, we have added two new commands in the PowerShell provider for generating the service configuration at design time in case you don’t want to rely on SO-Aware for resolving all that at runtime.

We have added a command for generating the configuration specific for SO-Aware

Get-SWServiceConfiguration -serviceversion "SampleService(1.0)" -configpath "d:\temp\MyConfig.config" -servicetype "Services.SampleService"

The arguments you pass to this command are the service version (A service that you already imported in the repository), the path to the configuration file, and the .NET type implementing the service. As result of executing this command, the following section will be added to the configuration file.

<configuration>
  <configSections>
    <section name="serviceRepository" type="Tellago.ServiceModel.Governance.ServiceConfiguration.ServiceRepositoryConfigurationSection, Tellago.ServiceModel.Governance.ServiceConfiguration" />
  </configSections>
  <serviceRepository url="http://localhost/soaware/servicerepository.svc">
    <services>
      <service name="ref:SampleService(1.0)" type="Services.SampleService" />
    </services>
  </serviceRepository>

</configuration>

That’s the configuration required by SO-Aware to resolve the service configuration at runtime.

In addition, if you don’t want to rely on SO-Aware at all, another command has been added to generate the WCF configuration section for a service. This command might also becomes handy if you want to deploy the configuration at design time in a cluster for example.

Get-SWWCFServiceConfiguration -serviceversion "SampleService(1.0)" -configpath "d:\temp\MyConfig.config" -servicetype "Samples.SampleService"

<configuration>
  <system.serviceModel>
    <services>    
      <service name="Samples.SampleService">
        <endpoint address="http://localhost:13749/SampleService.svc" contract="ISampleService" binding="basicHttpBinding" bindingConfiguration="basicHttp" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors />
      <endpointBehaviors />
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttp" />
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Both commands receive the same arguments, but the generated configuration is quite different as you can see.

Posted by cibrax
Filed under: , ,

One of the things that caught my attention when WCF Data Service was released a couple of years ago was the ability of using URI segments for passing queries directly to an underline linq provider. This represented a very powerful feature for allowing clients to filter and manipulate a large data result set on the server side with a simple API and without incurring in any unnecessary performance penalty (the queries are performed and resolved in the data source itself most of the times) and having all that logic implemented in the service itself.

I’ve always thought that this cool feature should be something that anyone could reuse in any service, and not something available in WCF data services only. For example, If you already had an existing REST service implementation, moving that logic to a WCF data service with OData support was only the option you had if you wanted to reuse that query support.  By moving your service to a WCF Data Service, you were also limiting your service to the content types supported by OData (Xml Atom and JSON), and it would only makes sense with services centered around the concepts of CRUD for manipulating data.

Fortunately, this functionality has been moved to a separated library and released as part of the new WCF Web APIs in wcf.codeplex.com. This means that you can now use the IQueryable support with almost the same linq operators that you already have in WCF Data Service as part of any existing WCF Http Service.

There is a new “QueryComposition” behavior that you can associate to one of the service operations to support querying over the response data.

private static List<Contact> contacts = new List<Contact>()
{
    new Contact { Name = "First Contact", Id = totalContacts++ },
    new Contact { Name = "Second Contact", Id = totalContacts++ },
    new Contact { Name = "Third Contact", Id = totalContacts++ },
    new Contact { Name = "Fourth Contact", Id = totalContacts++ },
};
 
[WebGet(UriTemplate = "")]
[QueryComposition]
public IEnumerable<Contact> Get()
{
    return contacts.AsQueryable();
}

In the example above, the service operation “Get” is returning a list of contacts in which some of the Linq query operators can be passed as part of the request URL as the “QueryComposition” attribute has been associated to the operation.

Therefore, you can do some of the following things,

Use the "#filter” segment to filter some of the data in the response resulset - http://localhost:8081/contacts/?$filter=Name eq 'First Contact'

Use the “#top” or “#skip” to get a subset of entries in the response - http://localhost:8081/contacts/?$skip=2&$top=1

And of course, many of the other supported operators available today as part of the OData spec can also be used.

In addition to what you can do on the server side, there is also a nice support on the client side with a new IQueryable implementation that knows how to pass many of the linq operators as part of the URL to the service. This new implementation is “WebQuery<T>” and it is part now of the HttpClient library also available as part of this WCF drop in codeplex.

string address = "http://localhost:8081/contacts/";
HttpClient client = new HttpClient(address);
IQueryable<Contact> contacts = client.CreateQuery<Contact>().Where(c => c.Name == "First Contact");

In the example above, the client library will submit the following request to the service, http://localhost:8081/contacts/?$filter=Name eq 'First Contact'. Several extensions methods have been added for the HttpClient class for creating new instances of WebQuery<T>.

This is only one of the cool features that the WCF team has added to the Http Stack, so I will explore the rest more in detail in following posts.

Posted by cibrax | 2 comment(s)
Filed under: , ,
More Posts