Contents tagged with WCF

  • Making WCF Web Async Apis

    One of the hidden gems that you can get today from the WCF Web Api source code in codeplex (wcf.codeplex.com) is the support for the task-based asynchronous model introduced in .NET 4.0. The new model simplifies a lot the way you do asynchronous stuff in .NET, and it’s going to get even better with the async support in C# 5.

    Read more...

  • Interop Bindings for WCF released in codeplex

    I am happy to announce that one of the projects in which Microsoft and Tellago have been collaborating together during the last few months was released as part of wcf.codeplex.com. The primary aim of this “WCF Interop Bindings” project is to simplify the work needed for making WCF services interoperable with other service stacks like Oracle WebLogic, IBM Websphere, Metro or Apache Axis. 

    Read more...

  • Extending the SO-Aware repository with custom metadata

    One of the main features that SO-Aware provides is the central repository for storing service artifacts (WSLD, schemas, bindings) and configuration that any organization generates. This central repository is completely exposed as an OData service that third party applications and tools can easily consume using Http.

    Read more...

  • Second round of Web Http Caching

    As I discussed in my previous post, web caching relies on specific headers that you need to use correctly on your services. That’s an http application protocol thing, and something that you can easily use in any application framework that treats Http as first citizen. This means that you don’t need to implement anything fancy or exclusively rely on an specific caching technology or components for doing ouput caching (e.g ASP.NET Cache).

    Read more...

  • Implementing caching in your WCF Web Apis

    One of the beauties of using Http as application protocol when building Web Apis is that you can reuse all the available infrastructure in the web to make your services scalable to the extreme. Caching is one of the fundamental aspects that makes scalability possible in the web today because it provides the following benefits when it is implemented correctly,

    Read more...

  • Configuring your WCF Web Apis

    Another major improvement in this new WCF Web Api release is the introduction of a fluent API for configuring your WCF Web Apis. All the available extensibility points in the current bits are now exposed through this API making possible to easily discover them.

    Read more...

  • Http Message Channels in WCF Web Apis Preview 4

    The new WCF Web Apis Preview 4 released yesterday in the wcf.codeplex.com introduced a new extensibility point for intercepting messages at channel level. The name for this new feature is “Http Message Channels” and the good thing is that you don’t need to rely anymore on the REST Starter Kit request interceptors for doing the same thing. Actually, a Http Message Channel is more useful as you can intercept either request or response messages, and also you get an Http message with all the context information you might need and not a WCF generic message, which usually requires some additional processing.

    Read more...

  • Troubleshooting your WCF Web Apis with AppFabric

    In this last post, I showed how the new WCF Web Apis could be integrated with AppFabric for pushing custom events to the AppFabric tracking database. A great thing about the monitoring infrastructure in AppFabric is that is uses ETW as mechanism for publishing the events, so your services are not hitting the database directly with all the performance penalties that database calls imply.  

    Read more...

  • Making your WCF Web Apis to speak in multiple languages

    One of the key aspects of how the web works today is content negotiation. The idea of content negotiation is based on the fact that a single resource can have multiple representations, so user agents (or clients) and servers can work together to chose one of them.

    The http specification defines several “Accept” headers that a client can use to negotiate content with a server, and among all those, there is one for restricting the set of natural languages that are preferred as a response to a request, “Accept-Language”. For example, a client can specify “es” in this header for specifying that he prefers to receive the content in spanish or “en” in english.

    However, there are certain scenarios where the “Accept-Language” header is just not enough, and you might want to have a way to pass the “accepted” language as part of the resource url as an extension. For example, http://localhost/ProductCatalog/Products/1.es” returns all the descriptions for the product with id “1” in spanish. This is useful for scenarios in which you want to embed the link somewhere, such a document, an email or a page. 

    Supporting both scenarios, the header and the url extension, is really simple in the new WCF programming model. You only need to provide a processor implementation for any of them.

    Let’s say I have a resource implementation as part of a product catalog I want to expose with the WCF web apis.

    [ServiceContract]
    [Export]
    public class ProductResource
    {
        IProductRepository repository;
     
        [ImportingConstructor]
        public ProductResource(IProductRepository repository)
        {
            this.repository = repository;
        }
     
        [WebGet(UriTemplate = "{id}")]
        public Product Get(string id, HttpResponseMessage response)
        {
            var product = repository.GetById(int.Parse(id));
            if (product == null)
            {
                response.StatusCode = HttpStatusCode.NotFound;
                response.Content = new StringContent(Messages.OrderNotFound);
            }
     
            return product;
        }
    }

    The Get method implementation in this resource assumes the desired culture will be attached to the current thread (Thread.CurrentThread.Culture). Another option is to pass the desired culture as an additional argument in the method, so my processor implementation will handle both options. This method is also using an auto-generated class for handling string resources, Messages, which is available in the different cultures that the service implementation supports. For example,

    Messages.resx contains “OrderNotFound”: “Order Not Found”

    Messages.es.resx contains “OrderNotFound”: “No se encontro orden”

    The processor implementation bellow tackles the first scenario, in which the desired language is passed as part of the “Accept-Language” header.

    public class CultureProcessor : Processor<HttpRequestMessage, CultureInfo>
    {
        string defaultLanguage = null;
     
        public CultureProcessor(string defaultLanguage = "en")
        {
            this.defaultLanguage = defaultLanguage;
            
            this.InArguments[0].Name = HttpPipelineFormatter.ArgumentHttpRequestMessage;
            this.OutArguments[0].Name = "culture";
        }
     
        public override ProcessorResult<CultureInfo> OnExecute(HttpRequestMessage request)
        {
            CultureInfo culture = null;
                        
            if (request.Headers.AcceptLanguage.Count > 0)
            {
                var language = request.Headers.AcceptLanguage.First().Value;
                culture = new CultureInfo(language);
            }
            else
            {
                culture = new CultureInfo(defaultLanguage);
            }
     
            Thread.CurrentThread.CurrentCulture = culture;
            Messages.Culture = culture;
     
            return new ProcessorResult<CultureInfo>
            {
                Output = culture
            };
        }
    }
     
    As you can see, the processor initializes a new CultureInfo instance with the value provided in the “Accept-Language” header, and set that instance to the current thread and the auto-generated resource class with all the messages. In addition, the CultureInfo instance is returned as an output argument called “culture”, making possible to receive that argument in any method implementation
     
    The following code shows the implementation of the processor for handling languages as url extensions.
     
    public class CultureExtensionProcessor : Processor<HttpRequestMessage, Uri>
    {
        public CultureExtensionProcessor()
        {
            this.OutArguments[0].Name = HttpPipelineFormatter.ArgumentUri;
        }
     
        public override ProcessorResult<Uri> OnExecute(HttpRequestMessage httpRequestMessage)
        {
            var requestUri = httpRequestMessage.RequestUri.OriginalString;
     
            var extensionPosition = requestUri.LastIndexOf(".");
     
            if (extensionPosition > -1)
            {
                var extension = requestUri.Substring(extensionPosition + 1);
     
                var query = httpRequestMessage.RequestUri.Query;
     
                requestUri = string.Format("{0}?{1}", requestUri.Substring(0, extensionPosition), query); ;
     
                var uri = new Uri(requestUri);
     
                httpRequestMessage.Headers.AcceptLanguage.Clear();
     
                httpRequestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(extension));
     
                var result = new ProcessorResult<Uri>();
     
                result.Output = uri;
     
                return result;
            }
     
            return new ProcessorResult<Uri>();
        }
    }

    The last step is to inject both processors as part of the service configuration as it is shown bellow,

    public void RegisterRequestProcessorsForOperation(HttpOperationDescription operation, IList<Processor> processors, MediaTypeProcessorMode mode)
    {
        processors.Insert(0, new CultureExtensionProcessor());
        processors.Add(new CultureProcessor());
    }

    Once you configured the two processors in the pipeline, your service will start speaking different languages :).

    Note: Url extensions don’t seem to be working in the current bits when you are using Url extensions in a base address. As far as I could see, ASP.NET intercepts the request first and tries to route the request to a registered ASP.NET Http Handler with that extension. For example, “http://localhost/ProductCatalog/products.es” does not work, but “http://localhost/ProductCatalog/products/1.es” does.

    Read more...