views:

349

answers:

4

Problem

My current project requires me to do different things based on different HTTP request headers for nearly every action.

Currently, I have one massive Controller (all for the same resource type), and every action method has an ActionName attribute (so that I can have multiple versions of the same action that takes the same parameters, but does different things) and a custom FilterAttribute (implemented almost exactly like the AcceptVerbsAttribute in Preview 5) that checks if certain headers have certain values.

I would really like to push the code into separate Controllers, and have the RouteTable select between them based on the headers, but can't think of the cleanest way to do this.

Example

For example, say I have a list of files. The service must process the request in one of two ways:

  1. The client wants a zip file, and passes "accept: application/zip" as a header, I take the list of files, pack them into a zip file, and send it back to the client.

  2. The client wants an html page, so it passes "accept: text/html", the site sends back a table-formatted html page listing the files.

A: 

I'm not sure you need separate controllers based on header; this structure sounds perfectly reasonable. If your controller is massive as you say, consider whether it's dealing with multiple resources, and if it is, perhaps it should be split into multiple controllers based on resource?

Aeon
Not currently working on multiple different resource types, just many different actions one the same resource, most of which need different handlers based on the 'Accept' header.
Alex Lyman
A: 

Not sure if it is possible, but it seems like this would be something like the AcceptVerbs attribute that was added in Preview 5. I'd take a look at how that was implemented (get the MVC source) to see if you can add something similar based on content type.

Bryant
I based the current code on the AcceptVerbs attribute. The example is a simple view of it, though. I currently have 24 different actions (with another 8 planned), each with 3-4 headers it differentiates on, totaling 86 different action methods.
Alex Lyman
+4  A: 

It sounds like you have slightly different behavior from your actions based on which header comes in. I would try to isolate the differences as much as possible.

For example, if the application logic is the same, but the only difference is how you render the response to the user, you might consider writing a custom ActionResult that takes different actions based on the Http headers.

However, if the logic is completely different, you could implement a custom Routing constraint (IRoutConstraint) that you attach to each route. Take a look at the implementation of HttpMethodConstraint for ideas.

Haacked
I can't believe I actually didn't think of this.
Alex Lyman
A: 

You should to look at this post. It describes implementation for json and xml responses based on http header.

zihotki