WCF Web API Preview 4 released!

15.04.2011 01:55Comments
The Preview 4 of the WCF Web API is now available in codeplex, for downloading the bits you can go here. A few things I have noticed about this latest release are.

Fluent Configuration API

In this release, we no longer need to inherit from HttpHostConfiguration in order to perform trivial configuration tasks. We can use the IHttpHostConfigurationBuilder class to pass to the MapServiceRoute method instead. Here is a snipet of code from the Contact sample project:
Code Snippet
  1. var config = HttpHostConfiguration
  2.     .Create()
  3.     .AddFormatters(
  4.         new ContactPngFormatter(),
  5.         new ContactFeedFormatter("http://localhost:9000/Contact"),
  6.         new VCardFormatter(),
  7.         new CalendarFormatter()).
  8.     SetResourceFactory(new MefResourceFactory(container)).
  9.     AddMessageHandlers(typeof (LoggingChannel), typeof (UriFormatExtensionMessageChannel));
  10.  
  11. SetMappings();
  12.  
  13. RouteTable.Routes.MapServiceRoute<ContactResource>("Contact", config);
Pretty cool right?

Message Handlers

Notice the “AddMessageHandlers” method from the fluent interface in the previous snipet. It takes a “params Type[]”, and those types have to inherit from DelegatingChannel and non-abstract. With this Message handlers you can manipulate the HttpRequestMessages and even avoid the execution of the request, and return a HttpResponseMessage without actually hitting the service operation (something very hard to accomplish in the previous version). Here is a LoggingChannel that comes with the bits:
Code Snippet
  1. public class LoggingChannel : DelegatingChannel
  2. {
  3.     public LoggingChannel(HttpMessageChannel handler)
  4.         :base(handler)
  5.     {
  6.         
  7.     }
  8.  
  9.     protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
  10.     {
  11.         System.Diagnostics.Trace.TraceInformation("Begin Request: {0} {1}", request.Method, request.RequestUri);
  12.         return base.SendAsync(request, cancellationToken);
  13.     }
  14.  
  15. }

IQueryable<T> Support

As of this release, there’s no need for the QueryComposition attribute anymore. Instead, you can just return an IQueryable<T> (as opposed to IEnumerable<T>).
Code Snippet
  1. [WebGet(UriTemplate = "")]
  2. public IQueryable<Contact> Get()
  3. {
  4.     return contacts.AsQueryable();
  5. }

Media type formatters

The MediaTypeProcessor has been replaced with MediaTypeFormatter (no longer a Processor), and the abstract methods WriteToStream and ReadFromStream have been renamed to OnWriteToStream and OnReadFromStream. The cool new feature of the Formatters are two virtual methods: OnCanReadType and OnCanWriteType which return whether this Formatter can read or write a particular Type. Take the following Formatter that can write a representation, but can’t read from a request.
Code Snippet
  1. public class CalendarFormatter : MediaTypeFormatter
  2. {
  3.     public CalendarFormatter()
  4.     {
  5.         this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/calendar"));
  6.     }
  7.  
  8.     public override object OnReadFromStream(Type type, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders)
  9.     {
  10.         throw new NotImplementedException();
  11.     }
  12.  
  13.     public override void OnWriteToStream(Type type, object value, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, System.Net.TransportContext context)
  14.     {
  15.         var singleContact = value as Contact;
  16.         if (singleContact != null)
  17.         {
  18.             WriteEvent(singleContact, stream);
  19.         }
  20.     }
  21.  
  22.     protected override bool OnCanReadType(Type type)
  23.     {
  24.         return false;
  25.     }
  26.  
  27.     protected override bool OnCanWriteType(Type type)
  28.     {
  29.         return (type == typeof (Contact));
  30.     }
  31.  
  32.     private void WriteEvent(Contact contact, Stream stream)
  33.     {
  34.         var dateFormat = "yyyyMMddTHHmmssZ";
  35.         var eventDate = DateTime.Now.ToUniversalTime().AddDays(2).AddHours(4);
  36.         var writer = new StreamWriter(stream);
  37.         writer.WriteLine("BEGIN:VCALENDAR");
  38.         writer.WriteLine("VERSION:2.0");
  39.         writer.WriteLine("BEGIN:VEVENT");
  40.         writer.WriteLine(string.Format("UID:{0}", contact.Email));
  41.         writer.WriteLine(string.Format("DTSTAMP:{0}", DateTime.Now.ToUniversalTime().ToString(dateFormat)));
  42.         writer.WriteLine(string.Format("DTSTART:{0}", eventDate.ToString(dateFormat)));
  43.         writer.WriteLine(string.Format("DTEND:{0}", eventDate.AddHours(1).ToString(dateFormat)));
  44.         writer.WriteLine("SUMMARY:Discuss WCF Web API");
  45.         writer.WriteLine("END:VEVENT");
  46.         writer.WriteLine("END:VCALENDAR");
  47.         writer.Flush();
  48.     }
  49. }
  All this, a more complete Contacts samples, and much more on this last release, download and enjoy!

comments powered by Disqus