Using UriTemplates with HttpRequestMessage

Topics: Web Api
Aug 4, 2011 at 5:54 AM

Does anyone have an example of how to combine UriTemplates with HttpRequestMessage? For instance, if I have the following class:

[OperationContract]
[WebGet(UriTemplate = "{contactId}"]
public HttpResponseMessage<Contact> Get(int contactId)
{
	var contact = _repository.Retrieve(contactId);
	var response = new HttpResponseMessage<Contact>(contact, HttpStatusCode.OK);
	return response;
}
then that all works nicely. However, if I now want to use ETags, I need access to the original request - so how do I change my method to give me access to the HttpRequestMessage, but still have my UriTemplate? The same obviously applies for DELETE, POST and PUT methods, where I might want to check some custom headers in the request before carrying out the operation.

 

Coordinator
Aug 4, 2011 at 7:21 AM

You can do this one of several ways.

1. Add HttpRequestMesssage as a property to your Get method. You don't put anything in the uri template, it will just work as it is a known convention.

2. An alternative apporach to inspecting headers is to use operation handlers or message handlers (channels). Message handlers are ideal if you just want to deal with HTTP request and response. If you want to do things related to a specific operaiton using Operation Handlers.

Glenn

 

Aug 4, 2011 at 4:47 PM

So my resulting code will look like this:

[OperationContract]
[WebGet(UriTemplate = "{contactId}"]
public HttpResponseMessage<Contact> Get(HttpRequestMessage request, int contactId)
{
	var header = request.Headers.GetValues("SomeHeader").FirstOrDefault();
	// Do stuff based on the header

	var contact = _repository.Retrieve(contactId);
	var response = new HttpResponseMessage<Contact>(contact, HttpStatusCode.OK);
	return response;
}

Is that right? I'm really starting to dig the work you guys have put into this, it just goes to show the amount of ceremony you have to go through to get WCF to do more than the basics. Not having to wrap the various WCF context classes and write IoC providers etc is a big productivity boost, keep up the good work!

Out of interest, given that ETags and LastModified are likely to be common requirements for people, what's the current best guidance for using them with Web API?

Coordinator
Aug 4, 2011 at 6:21 PM

For ETags, our recommendation is you handle that via a channel. We used to recommend operation handlers with an entity implementing some sort of IEntityTag interface, but since then we've learned that is unnecessary.

Here's a sample of one we implemented a while back: http://codepaste.net/4w6c6i. You'll probably want to change the backing store to not be dictionary but some service.

In terms of LastModified I would also handle that via a handler preferably, but you could push that upstream.