I want to select an Action of my Controller based on the Media Type requested in the Accept header.
For example, I have a resource called a subject. Its assigned route is:
GET /subjects/{subjectId:int}
Normally, the browser is requesting text/html
, which is fine. The default Media Formatter handles this great.
Now, I have custom logic I want to perform when this same route is accessed with an accept header specifying application/pdf
as the accepted Media Type.
I could create a custom Media Formatter, but, to my understanding, this would mean that any route that is requested with the Accept header set to application/pdf
would also run through this Media Formatter. This is unacceptable.
In Java, there is an annotation called @Produces
:
The @Produces annotation is used to specify the MIME media types or representations a resource can produce and send back to the client. If @Produces is applied at the class level, all the methods in a resource can produce the specified MIME types by default. If applied at the method level, the annotation overrides any @Produces annotations applied at the class level.
This would allow me to do the following:
namespace MyNamespace
{
[RoutePrefix("subjects")]
public class SubjectsController : Controller
{
[Route("{subjectId:int}")]
[HttpGet]
public ActionResult GetSubject(int subjectId)
{
}
[Route("{subjectId:int}")]
[HttpGet]
[Produces("application/pdf")]
public ActionResult GetSubjectAsPdf(int subjectId)
{
//Run my custom logic here to generate a PDF.
}
}
}
There is no Produces Attribute in .NET that I can find, of course, so this doesn't work. I haven't been able to find a similar attribute, either.
I could of course manually check the header within the body of the action, and redirect it to another action, but that seems hackish at best.
Is there a mechanism in .NET 4.5 that I may use to pull this off that I'm overlooking or missing?
(I'm using MVC 5.2.2 from NuGet repository)
After searching around the Internet for awhile, I came up with the idea that this would be best accomplished by creating an
ActionMethodSelectorAttribute
.The following is a very naive, first-pass implementation of a
ProducesAttribute
that I wrote with the eventual intent of mimicking Java's Produces annotation:It is meant to be used with Attribute Routing, and can be applied as follows: