As many of the existing Http APIs for Cloud Services, AWS also provides a set of different platform SDKs for hiding many of complexities present in the APIs. While there is a platform SDK for .NET, which is open source and available in C#, that SDK does not work in Win8 Metro Applications for the changes introduced in WinRT. WinRT offers a complete different set of APIs for doing I/O operations such as doing http calls or using cryptography for signing or encrypting data, two aspects that are absolutely necessary for consuming AWS. All the I/O APIs available as part of WinRT are asynchronous, and uses the TPL model for .NET applications (HTML and JavaScript Metro applications use a model based in promises, which is similar concept). 

In the case of S3, the http Authorization header is used for two purposes, authenticating clients and make sure the messages were not altered while they were in transit. For doing that, it uses a signature or hash of the message content and some of the headers using a symmetric key (That's just one of the available mechanisms). Windows Azure for example also uses the same mechanism in many of its APIs.

There are three challenges that any developer working for first time in Metro will have to face to consume S3, the new WinRT APIs, the asynchronous nature of them and the complexity introduced for generating the Authorization header. Having said that, I decided to write this post with some of the gotchas I found myself trying to consume this Amazon service.

1. Generating the signature for the Authorization header

All the cryptography APIs in WinRT are available under Windows.Security.Cryptography namespace. Many of operations available in these APIs uses the concept of buffers (IBuffer) for representing a chunk of binary data. As you will see in the example below, these buffers are mainly generated with the use of static methods in a WinRT class CryptographicBuffer available as part of the namespace previously mentioned.

private string DeriveAuthToken(string resource, string httpMethod, string timestamp)
{
   var stringToSign = string.Format("{0}\n" +
      "\n" +
      "\n" +
      "\n" +
      "x-amz-date:{1}\n" +
      "/{2}/", httpMethod, timestamp, resource);

   var algorithm = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");

   var keyMaterial = CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(this.secret));

   var hmacKey = algorithm.CreateKey(keyMaterial);

   var signature = CryptographicEngine.Sign(
                hmacKey,
                CryptographicBuffer.CreateFromByteArray(Encoding.UTF8.GetBytes(stringToSign))
            );

   return CryptographicBuffer.EncodeToBase64String(signature);
}

The algorithm that determines the information or content you need to use for generating the signature is very well described as part of the AWS documentation. In this case, this method is generating a signature required for creating a new bucket. A HmacSha1 hash is computed using a secret or symetric key provided by AWS in the management console.

2. Sending an Http Request to the S3 service

WinRT also ships with the System.Net.Http.HttpClient that was first introduced some months ago with ASP.NET Web API. This client provides a rich interface on top the traditional WebHttpRequest class, and also solves some of limitations found in this last one. There are a few things that don't work with a raw WebHttpRequest such as setting the Host header, which is something absolutely required for consuming S3. Also, HttpClient is more friendly for doing unit tests, as it receives a HttpMessageHandler as part of the constructor that can fake to emulate a real http call. This is how the code for consuming the service with HttpClient looks like,

public async Task<S3Response> CreateBucket(string name, string region = null, params string[] acl)
{
   var timestamp = string.Format("{0:r}", DateTime.UtcNow);

    var auth = DeriveAuthToken(name, "PUT", timestamp);

    var request = new HttpRequestMessage(HttpMethod.Put, "http://s3.amazonaws.com/");
    request.Headers.Host = string.Format("{0}.s3.amazonaws.com", name);
    request.Headers.TryAddWithoutValidation("Authorization", "AWS " + this.key + ":" + auth);
    request.Headers.Add("x-amz-date", timestamp);

    var client = new HttpClient();
    var response = await client.SendAsync(request);

    return new S3Response
    {
         Succeed = response.StatusCode == HttpStatusCode.OK,
         Message = (response.Content != null) ? 
            await response.Content.ReadAsStringAsync() : null
     };
 }

You will notice a few additional things in this code. By default, HttpClient validates the values for some well-know headers, and Authorization is one of them. It won't allow you to set a value with ":" on it, which is something that S3 expects. However, that's not a problem at all, as you can skip the validation by using the TryAddWithoutValidation method.
Also, the code is heavily relying on the new async and await keywords to transform all the asynchronous calls into synchronous ones. In case you would want to unit test this code and faking the call to the real S3 service, you should have to modify it to inject a custom HttpMessageHandler into the HttpClient. The following implementation illustrates this concept,

In case you would want to unit test this code and faking the call to the real S3 service, you should have to modify it to inject a custom HttpMessageHandler into the HttpClient. The following implementation illustrates this concept,

public class FakeHttpMessageHandler : HttpMessageHandler
{
  HttpResponseMessage response;

  public FakeHttpMessageHandler(HttpResponseMessage response)
  {
       this.response = response;
   }

   protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
   {
      var tcs = new TaskCompletionSource<HttpResponseMessage>();
            
      tcs.SetResult(response);

      return tcs.Task;
    }
}

You can use this handler for injecting any response while you are unit testing the code.

Posted by cibrax
Filed under: , ,

One scenario that is very common in ASP.NET MVC is to bind form data (data posted with the media type application/x-www-form-urlencoded)  to individual parameters or a form collection in a controller action. However, that scenario does not work quite the same in ASP.NET Web API as the body content is treated a forward-only stream that can only be read once. 

If you define an action with multiple simple type arguments such as the one shown bellow, the model binding runtime will try to map those by default from the request URI (query string or route data). 

public void Post(int id, string value)
{
}

That data never comes from the body content unless you decorate the argument with the [FromBody] attribute. However, only one argument in the action can be decorated with this attribute, and you get an exception when you try to decorate more than one. Nevertheless, the desired effect is far from what you would expect.

If you define an action as follow,

public void Post([FromBody]int id)
{
}

And you POST a form with the following data,

http://localhost:64561/api/values

METHOD: POST

CONTENT-TYPE: application/x-www-form-urlencoded

BODY: id=4

Nothing will be mapped. It does not matter you defined a single parameter with the same as the one posted in the body.

If you really want to have a single type argument mapped to the body content, you have to POST a message with the following content

http://localhost:64561/api/values

METHOD: POST

CONTENT-TYPE: application/x-www-form-urlencoded

BODY: =4

As you can see, no key defined so the whole is mapped to our argument in the action. That’s the default behavior for single types. If you want to change that behavior, the framework is completely extensible and you can replace the whole model binding infrastructure included out of the box for one that you find more useful as it is explained here by Mike Stalls (which shows how you can replicate the same model used by ASP.NET MVC).

For complex types, the framework includes two MediaTypeFormatter implementations. The first one is FormUrlEncodedMediaTypeFormatter, which knows how to map every key/value in the form data to a FormDataCollection or a JTokenType (a dynamic type for expressing JSON available as part of the Json.NET library). These two are useful when you want to get access to all the values in form in a generic manner. You define for example a controller that receives a FormDataCollection instance like this,

public void Post(FormDataCollection form)
{
}

The second one is JQueryMvcFormUrlEncodedFormatter, which derives from the first one and knows how to map the form data to a concrete type representing a model. For example, a model defined as follow will match a body content with the keys “Id” and “Value”

public class MyModel
{
   public int Id { get; set; }
   public string Value { get; set; }
}

Therefore, your controller action can either receive a generic form collection (or a JTokenType) or a complex model type as any of these two will handle the deserialization of the body content type into the expected model.

Posted by cibrax
Filed under: , ,

One of main characteristics of MediaTypeFormatter’s in ASP.NET Web API is that they leverage the Task Parallel Library (TPL) for reading or writing an model into an stream. When you derive your class from the base class MediaTypeFormatter, you have to either implement the WriteToStreamAsync or ReadFromStreamAsync methods for writing or reading a model from a stream respectively.

These two methods return a Task, which internally does all the serialization work, as it is illustrated bellow.

public abstract class MediaTypeFormatter
{
  public virtual Task WriteToStreamAsync(Type type, object value, 
     Stream writeStream, HttpContent content, TransportContext transportContext);
  public virtual Task<object> ReadFromStreamAsync(Type type, Stream readStream, 
     HttpContent content, IFormatterLogger formatterLogger);
}
 

However, most of the times, serialization is a safe operation that can be done synchronously. In fact, many of the serializer classes you will find in the .NET framework only provide sync methods. So the question is, how you can transform that synchronous work into a Task ?.

Creating a new task using the method Task.Factory.StartNew for doing all the serialization work would be probably the typical answer. That would work, as a new task is going to be scheduled. However, that might involve some unnecessary context switches, which are out of our control and might be affect performance on server code specially.  

If you take a look at the source code of the MediaTypeFormatters shipped as part of the framework, you will notice that they actually using another pattern, which uses a TaskCompletionSource class.

public Task WriteToStreamAsync(Type type, object value, Stream writeStream, 
HttpContent content, TransportContext transportContext)
{
 
  var tsc = new TaskCompletionSource<AsyncVoid>();
  tsc.SetResult(default(AsyncVoid));
 
  //Do all the serialization work here synchronously
 
  return tsc.Task;
}
 
/// <summary>
/// Used as the T in a "conversion" of a Task into a Task{T}
/// </summary>
private struct AsyncVoid
{
}

They are basically doing all the serialization work synchronously and using a TaskCompletionSource for returning a task already done.

To conclude this post, this is another approach you might want to consider when using serializers that are not compatible with an async model.

Update: Henrik Nielsen from the ASP.NET team pointed out the existence of a built-in media type formatter for writing sync formatters. BufferedMediaTypeFormatter http://t.co/FxOfeI5x

Posted by cibrax
Filed under: , ,

La serie de videos que grabe con Miguel Angel Saenz y Ariel Schapiro de Microsoft Argentina acerca del proyecto “Liike” de Patterns & Practices para desarrollos de aplicaciones mobiles con HTML 5 ha sido publicada en channel9.

Les dejo la lista de videos para que los puedan ir viendo y conociendo un poco mas con este proyecto mas que interesante.

http://channel9.msdn.com/posts/1Serie-HTML5-para-dispositivos-mviles-Proyecto-Liike-parte-1-introduccin
http://channel9.msdn.com/posts/2Serie-HTML5-para-dispositivos-mviles-Proyecto-Liike-parte-2-overview-de-aplicacin-Mileage-Stats
http://channel9.msdn.com/posts/3Serie-HTML5-para-dispositivos-mviles-Proyecto-Liike-parte-3-determinacin-de-vista-en-html-a-mostrar
http://channel9.msdn.com/posts/4Serie-HTML5-para-dispositivos-mviles-Proyecto-Liike-parte-4-Single-Page-application
http://channel9.msdn.com/posts/5Serie-HTML5-para-dispositivos-mviles-Proyecto-Liike-parte-5-nuevos-controles-HTML5-
http://channel9.msdn.com/posts/6Serie-HTML5-para-dispositivos-mviles-Proyecto-Liike-parte-6-Botn-Switch-to-Desktop-Site
http://channel9.msdn.com/posts/7Serie-HTML5-para-dispositivos-mviles-Proyecto-Liike-parte-7-Testing-de-aplicaciones-mviles-en-HTML5

Posted by cibrax

Apache Cordova is one of those projects that recently caught my attention for developing applications in mobile. This project previously known as PhoneGap was donated by Adobe to the Apache Foundation to be part of a new and attractive open source alternative for developing mobile applications.  If you haven’t heard of it before, it basically provides the required infrastructure to run native applications in different mobile platforms such as IOS, Android, and Windows Phone 7 using an hybrid approach with an embedded browser. There is a thin native layer that provides access to different native features in phone through an standard object model in JavaScript, so the developers can write their applications using HTML 5 and have access to different features through that model. Therefore, the two most important components in this project are the native layer and the JavaScript component model, which are supported across the different platforms.

The Microsoft Interoperability team collaborated as part of the project to support Win7 phone as another available platform, which was announced by Abu Obeida in December last year. Another major announcement these days was the support for a Metro theme in JQuery Mobile, which gives the ability to give applications written in HTML 5 for this platform the same look and feel as a native applications.

If you want to know more about the platform, there is an excellent introductory article written by Colin Eberhardt for the MSDN Magazine, “Develop HTML Windows Phone Apps with Apache Cordova”

One the things I noticed in the project, is that there is available a project template in Visual Studio for creating the initial application. However, you need to manually deploy that template in the right folder to make it available in Visual Studio, which might be an error prone task. I decided to make a little contribution to the project and write an Visual Studio extension (a vsix package) to automatically deploy the template, which I am not sure yet if it is going to be approved or not, but I think it is a nice thing to have for easing adoption. This is part of the fork associated to my user in case you want to use it.

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

A common scenario for many web applications running in the cloud is to integrate with existing systems through web services (no matter the messaging style they use). Although in these scenarios, an SLA is typically used as an agreement between the two parties to assure certain level of availability, many things can still fail. Therefore, it is always a good idea to have a mechanism in place to handle any possible error condition and retry the execution when it is possible.

As example, you could have a web application that calls an online CRM system (like Salesforce.com or MS Dynamics) for allowing the users to report incidents. In that scenario, we can not assume any possible call to the CRM system will always succeed. On the other hand, this kind of call does not require an immediate response for the user, so it can be scheduled for later execution and retried if something unexpected happens.

A persistent storage for the messages like a queue is always a good choice for decoupling clients from services, and also accomplish the goal previously discussed. When you move to Windows Azure, there are two different queue offerings, Queues as part of the Storage service, and Queues (or Topics) as part of the Service Bus.

The Service Bus SDK provides a programming model on top of WCF for consuming or sending messages to the queues, which makes this solution very appealing for this scenario. The Service Bus also provides Topics, which are an specific kind of queues that supports subscriptions.

By using Service Bus Queues, the calls to any third party service could be eventually wrapped up in WCF services that are invoked by the web application. The following image illustrates the possible architecture,

queues

One of the core classes in the WCF programming model for the Service Bus Queues is BrokeredMessage. This class represents a message that can be sent to/from an existing queue, and contains a lot of  standard properties such as MessageId, ReplyTo, SessionId or Label to name a few. It also contain a dictionary for custom properties that an application can assign to the message.

In the example above, the MessageId property can be used to correlate the input and out messages in the queue and update the corresponding result in the web application. The WCF service can also use the ReplyTo property, which represents the queue name in which the response should go. Sessions is another concept supported in the Service Bus Queues, which are useful for correlating a set of messages as a batch for processing.   This is something optional and requires the queue to support sessions when they are created.

In WCF, the BrokeredMessage is assigned to the service call with a message property BrokeredMessageProperty as it is illustrated bellow,

var channelFactory = new ChannelFactory<ICRMServiceClient>("crminput");
var clientChannel = channelFactory.CreateChannel();
 
// Use the OperationContextScope to create a block within which to access the current OperationScope
using (var scope = new OperationContextScope((IContextChannel)clientChannel))
{
    // Create a new BrokeredMessageProperty object
    var property = new BrokeredMessageProperty();
 
    // Use the BrokeredMessageProperty object to set the BrokeredMessage properties
    property.Label = "Incident";
    property.MessageId = Guid.NewGuid().ToString();
    property.ReplyTo = "sb://xxx.servicebus.windows.net/input";
 
    // Add BrokeredMessageProperty to the OutgoingMessageProperties bag provided 
    // by the current Operation Context 
    OperationContext.Current.OutgoingMessageProperties.Add(BrokeredMessageProperty.Name, property);
    
    //Do the service call here
 
 
}

On the service side, the BrokeredMessageProperty instance can be retrieved in a similar way

var incomingProperties = OperationContext.Current.IncomingMessageProperties;
var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;

Another important feature in the programming model for supporting execution retries in our example is the ReceiveContext. By decorating the WCF service contract with the ReceiveContextEnabled attribute, we can manually specify whether the operation was successfully completed or not. If the operation was not completed, the message will remain in the queue and the operation will be executed again next time.

[ServiceContract()]
public interface ICRMService
{
    [OperationContract(IsOneWay=true)]
    [ReceiveContextEnabled(ManualControl = true)]
    void CreateCustomer(Customer customer);
}
 
The following code shows how the operation implementation looks like,
 
var incomingProperties = OperationContext.Current.IncomingMessageProperties;
var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;
 
//Complete the Message
ReceiveContext receiveContext;
if (ReceiveContext.TryGet(incomingProperties, out receiveContext))
{
   //Do Something                
   receiveContext.Complete(TimeSpan.FromSeconds(10.0d));
}
else
{
   throw new InvalidOperationException("...");
}

As you can see, the ReceiveContext instance is marked as complete or implicitly set as not complete when an exception is thrown.

The assemblies for the Service Bus SDK are available as part of a Nuget package “Windows Azure Service Bus”. As part of the package registration, all the required configuration extensions for the WCF such as custom bindings and behaviors are also added in the application configuration file.

NetMessagingBinding is the one you need to use for sending or receiving messages from a queue. That binding is constantly polling the queues for detecting new messages, and activating the WCF service when a new message arrives. For that reason, you need to keep the web application App pool running all the time. This can be accomplished in Windows Azure with a simple approach as this one mentioned by Christian Weyer in this post.

Posted by cibrax
Filed under: , ,

Moving to the cloud can represent a big challenge for many organizations when it comes to reusing existing infrastructure. For applications that drive existing business processes in the organization, reusing IT assets like active directory represent good part of that challenge. For example, a new web mobile application that sales representatives can use for interacting with an existing CRM system in the organization.

In the case of Windows Azure, the Access Control Service (ACS) already provides some integration with ADFS through WS-Federation. That means any organization can create a new trust relationship between the STS running in the ACS and the STS running in ADFS. As the following image illustrates, the ADFS running in the organization should be somehow exposed out of network boundaries to talk to the ACS. This is usually accomplish through an ADFS proxy running in a DMZ.

ActiveDirectoryForCloud1

This is the official story for authenticating existing domain users with the ACS.  Getting an ADFS up and running in the organization, which talks to a proxy and also trust the ACS could represent a painful experience. It basically requires  advance knowledge of ADSF and exhaustive testing to get everything right. 

However, if you want to get an infrastructure ready for authenticating your domain users in the cloud in a matter of minutes, you will probably want to take a look at the sample I wrote for talking to an existing Active Directory using a regular WCF service through the Service Bus Relay Binding.

You can use the WCF ability for self hosting the authentication service within a any program running in the domain (a Windows service typically). The service will not require opening any port as it is opening an outbound connection to the cloud through the Relay Service. In addition, the service will be protected from being invoked by any unauthorized party with the ACS, which will act as a firewall between any client and the service. In that way, we can get a very safe solution up and running almost immediately.

To make the solution even more convenient, I implemented an STS in the cloud that internally invokes the service running on premises for authenticating the users. Any existing web application in the cloud can just establish a trust relationship with this STS, and authenticate the users via WS-Federation passive profile with regular http calls, which makes this very attractive for web mobile for example.

ActiveDirectoryForCloud2

This is how the WCF service running on premises looks like,

[ServiceBehavior(Namespace = "http://agilesight.com/active_directory/agent")]
public class ProxyService : IAuthenticationService
{
    IUserFinder userFinder;
    IUserAuthenticator userAuthenticator;
 
    public ProxyService()
        : this(new UserFinder(), new UserAuthenticator())
    {
    }
 
    public ProxyService(IUserFinder userFinder, IUserAuthenticator userAuthenticator)
    {
        this.userFinder = userFinder;
        this.userAuthenticator = userAuthenticator;
    }
 
    public AuthenticationResponse Authenticate(AuthenticationRequest request)
    {
        if (userAuthenticator.Authenticate(request.Username, request.Password))
        {
            return new AuthenticationResponse
            {
                Result = true,
                Attributes = this.userFinder.GetAttributes(request.Username)
            };    
        }
 
        return new AuthenticationResponse { Result = false };
    }
}

Two external dependencies are used by this service for authenticating users (IUserAuthenticator) and for retrieving user attributes from the user’s directory (IUserFinder). The UserAuthenticator implementation is just a wrapper around the LogonUser Win Api.

The UserFinder implementation relies on Directory Services in .NET for searching the user attributes in an existing directory service like Active Directory or the local user store.

public UserAttribute[] GetAttributes(string username)
{
    var attributes = new List<UserAttribute>();
 
    var identity = UserPrincipal.FindByIdentity(new PrincipalContext(this.contextType, this.server, this.container), IdentityType.SamAccountName, username);
    if (identity != null)
    {
        var groups = identity.GetGroups();
        
        foreach(var group in groups)
        {
            attributes.Add(new UserAttribute { Name = "Group", Value = group.Name });
        }
        
        if(!string.IsNullOrEmpty(identity.DisplayName))
            attributes.Add(new UserAttribute { Name = "DisplayName", Value = identity.DisplayName });
        
        if(!string.IsNullOrEmpty(identity.EmailAddress))
            attributes.Add(new UserAttribute { Name = "EmailAddress", Value = identity.EmailAddress });
    }
 
    return attributes.ToArray();
}
As you can see, the code is simple and uses all the existing infrastructure in Azure to simplify a problem that looks very complex at first glance with ADFS.

All the source code for this sample is available to download (or change) in this GitHub repository,

https://github.com/AgileSight/ActiveDirectoryForCloud

Posted by cibrax

In case you are developing a new web application with Node.js for Windows Azure, you might notice there is no easy way to debug the application unless you are developing in an integrated IDE like Cloud9. For those that develop applications locally using a text editor (or WebMatrix) and Windows Azure Powershell for Node.js, it requires some steps not documented anywhere for the moment.

I spent a few hours on this the other day I practically got nowhere until I received some help from Tomek and the rest of them. The IISNode version that currently ships with the Windows Azure for Node.js SDK does not support debugging by default, so you need to install the IISNode full version available in the github repository

Once you have installed the full version, you need to enable debugging for the web application by modifying the web.config file

<iisnode 
     debuggingEnabled="true"
     loggingEnabled="true"
     devErrorsEnabled="true"
   />

The xml above needs to be inserted within the existing “<system.webServer/>” section.

The last step is to open a WebKit browser (e.g. Chrome) and navigate to the URL where your application is hosted but adding the segment “/debug” to  the end. The full URL to the node.js application must be used, for example, http://localhost:81/myserver.js/debug

That should open a new instance of Node inspector on the browser, so you can debug the application from there.

Enjoy!!

Posted by cibrax
Filed under: , ,

Hypermedia is one of those concepts really hard to grasp when building Http aware APIs (or Web API’s). As human beings, we are constantly dealing with hypermedia in the existing web by following links or posting data from some forms that take us to a next level.

We typically remember the entry point or URL for the retrieving the home page of web site, and we can move from there on to different sections using hypermedia artifacts. Those URL usually tend to be nice and easy to remember, but they don’t have to be as it is not something http by itself mandates. We could rely on a search engine like Google or Bing to find those URLs for us. You can even use some cryptographic URLs for the web pages in your website, and still provide a nice experience for the user by proving the right links to browse the content.

When you build Http API’s for being consumed for other systems, the history is not any different. There is no any reason for client applications to remember all the possible resources and their location (URLs) if the server can provide those. Hardcoding URL’s on the client side is a bad thing for two main reasons,

  1. The server can change the location for an specific resource, so all the clients having a hardcoded URL for that resource will break.
  2. It pushes some knowledge about the application state workflow to the client side. What happens if an action in a resource is only available for a given state, shall we put that logic in any possible API consumer ?. Definitely not, the server should always mandate what can be done or not with a resource. For example, if the state of a purchase order is canceled, the client application application shouldn’t be allowed to submit that PO. If we have an user in front of an UI using that API, he shouldn’t see the submit button enabled (That logic for enabling or disabling the button could be driven by the server using links).

This is one of the gray areas that typically differentiates a regular Web API’s from a RESTful API, but there are some other constraints that also applies, so this discussing about RESTful services probably don’t make sense in most cases. What matters in the end is that the API uses HTTP correctly as application protocol and leverage hypermedia when it is possible. By enabling Hypermedia, you can create self-discoverable APIs, which are not an excuse for not providing documentation as I usually hear, but are more flexible in terms of updatability.

Many of the media types we use nowadays for building Web API’s such as JSON or XML don’t have a built-in concept for representing hypermedia links as HTML does with links and forms. You can leverage those media types by defining a way to express hypermedia, but again, it requires client to understand how the hypermedia semantics are defined on top of those. Other media types like XHtml or ATOM already support some of the hypermedia concepts like links or forms.

By moving forward with this idea of Hypermedia API on top of JSON or XML, Mike Kelly wrote a draft for an specific media type called “HAL”.   HAL extends JSON and XML with all the semantics required to express resources and their links. This fragment from the spec draft illustrates how an order can be modeled using the xml variant of HAL,

<resource href="/orders">
  <link rel="next" href="/orders?page=2" />
  <link rel="search" href="/orders?id={order_id}" />
  <resource rel="order" href="/orders/123">
    <link rel="customer" href="/customer/bob" title="Bob Jones &lt;bob@jones.com>" />
    <resource rel="basket" href="/orders/123/basket">
      <item>
        <sku>ABC123</sku>
        <quantity>2</sku>
        <price>9.50</price>
      </item>
      <item>
        <sku>GFZ111</sku>
        <quantity>1</quantity>
        <price>11.00</price>
      </item>
    </resource>
    <total>30.00</total>
    <currency>USD</currency>
    <status>shipped</status>
    <placed>2011-01-16</placed>
  </resource>
  <resource rel="order" href="/orders/124">
    <link rel="customer" href="/customer/jen" title="Jen Harris &lt;jen@internet.com>" />    
    <resource rel="basket" href="/orders/124/basket">
      <item>
        <sku>KLM222</sku>
        <quantity>1</sku>
        <price>9.00</price>
      </item>
      <item>
        <sku>HHI50</sku>
        <quantity>1</quantity>
        <price>11.00</price>
      </item>
    </resource>
    <total>20.00</total>
    <currency>USD</currency<status>processing</status>
    <placed>2011-01-16</placed>
  </resource>
</resource>

You can see the different entities in your system can be modeled and represented as resources, which are linked, and attributes like “rel” or “href” are used to express the role of the entity and it’s location. Steve Michelotti created an specific formatter for HAL in WCF Web API available here, but it hasn’t be updated to the latest ASP.NET Web API version yet.

I have been able to see two different kinds of hypermedia APIs over the years. APIs returning links for representing state transitions or linked resources that put some out of band assumptions on the consumer for how the transition should be executed. For example, consider the following example with the representation of a PO.

<purchaseOrder>
  <id>90</id>
  <sku>AJJ34</sku>  
  <link rel="customer" href="/customers/foo"/>
  <link rel="approve" href="/po/90/approve"/>
  <link rel="cancel" href="/po/90/cancel"/>
</purchaseOrder>

The representation contains a link for retrieving the representation of the associated customer (which assumes the client should send an HTTP to that URL for getting the representation), and two additional links for approving or canceling the PO (which also assumes the client knows how to post a message to those URLs). You see, the consumer is still coupled to the Web API implementation with some out of band details, but still is self-discoverable and the consumer can determine which actions can be executed over that resource (See the associated customer details, approve it or cancel it).

There are also other kind of APIs that use Forms as you would find them in the HTML or XHTML media types. Good part of these APIs are driven by forms submissions. Let’s see an example to illustrate the concept.

<ul id="purchaseOrder">
  <li id="id">90</li>
  <li id="sku">AJJ34</li>  
</ul>
<a href="/customers/foo" rel="customer"/>
<a href="/po/90/approve_form" rel="approve"/>
<a href="/po/90/cancel_form" rel="cancel"/>

The purchase order is returned this time as an XHTML representation and contains links which basically supports the HTTP GET semantics. An HTTP GET to the “customer” link would return the associated customer representation. However, an HTTP GET to the “approve” or “cancel” links would return an http form this time for approving or canceling the order.

<form action="/po/90/approve" method="POST">
  <input type="hidden" id="id">90</input>
  <input type="hidden" id="___forgeryToken">XXXXXXXX</input>
</form>

The consumer now has been decoupled of certain details for approving the order for example. It only needs to submit this form using an HTTP POST to the URL specified in the action attribute. The server can also includes additional information in the form as a forgery token for example to avoid “Cross-site Request Forgery” (CSRF) attacks.

Posted by cibrax
Filed under: , ,

ASP.NET Web API provides a very similar model to MVC for resolving dependencies using a service locator pattern. What you basically do is to provide the implementation of that service locator to return any of the requested dependencies, and that implementation is typically tied to a DI container. 

The service locator can be injected into the Web API runtime using the ServiceResolver entry in the global configuration object (GlobalConfiguration.Configuration.ServiceResolver), which basically supports different overloads.

public void SetResolver(IDependencyResolver resolver);
public void SetResolver(object commonServiceLocator);
public void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices);

The first overload receives an instance of a IDependencyResolver implementation, which provides two methods for resolving one or multiple dependencies.

public interface IDependencyResolver
{
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}

GetService should return null if the dependency can not resolved. GetServices should return an empty IEnumerable if the same thing happens.

The second overload uses reflection for invoking the same two methods, GetService and GetServices.

The third overload receives a set of Func delegates for doing the same thing.

Autofac already provides a very smooth integration with ASP.NET Web API through a set of assemblies available in the “Autofac ASP.NET MVC integration” nuget package. The bad news is that you can not use the DepedencyResolver implementation in that package as it is not compatible with the one required by ASP.NET Web API.

The AutofacDepedencyResolver class in that package implements System.Web.Mvc.IDependencyResolver, while ASP.NET Web API expects a System.Web.Http.Services.IDependencyResolver implementation. Nothing that we can not fix with  a simple few lines of code. We can reuse the existing implementation through the third overload that receives a set of delegates.

The following code snippet illustrates how you can register all dependencies in the Autofac container and use that for resolving all the Web API dependencies,

ContainerBuilder builder = new ContainerBuilder();
 
builder.RegisterType<ContactRepository>()
    .As<IContactRepository>()
    .InstancePerHttpRequest();
 
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 
IContainer container = builder.Build(); 
 
var resolver = new AutofacDependencyResolver(container);
 
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
    t => resolver.GetService(t),
    t => resolver.GetServices(t));

One the things you can do with Autofac is to set the lifetime of the dependencies instances to be equal to a http request lifetime by using the “InstancePerHttpRequest” method. I also created a simple extension method “RegisterApiControllers” to automatically register all the existing Api controllers in the the project into the DI container.

public static class RegistrationExtensions
{
    public static IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle> RegisterApiControllers(this ContainerBuilder builder, params Assembly[] controllerAssemblies)
    {
        return
            from t in builder.RegisterAssemblyTypes(controllerAssemblies)
            where typeof(IHttpController).IsAssignableFrom(t) && t.Name.EndsWith("Controller")
            select t;
    }
}

Using the code above, you should be able to use a API controller that looks like this (The contact repository is injected as a depedency)

public class ContactController : ApiController
{
    IContactRepository repository;
 
    public ContactController(IContactRepository repository)
    {
        this.repository = repository;
    }
Posted by cibrax | 2 comment(s)
Filed under: , ,
More Posts « Previous page - Next page »