3

I need to generate PDF reports of certain data sets when the client passes a certain parameter (?print) in the query string of a Web API route. Now I'm wondering if a custom action filter is a suitable way of doing this.

public class ReportFilterAttribute : ActionFilterAttribute {

    public ReportFilterAttribute(string controller, string layoutPath) {

    }

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        // look for parameter ?print in the request query string
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
       // load layout file
       // fill in data returned by the api
       // manipulate response to return a filestream instead of json data
    }
}
  1. Is there a way to prevent OnActionExecuted being called, e.g. when there is no parameter ?print available?
  2. Is it an acceptable practice to return either a filestream (PDF) or JSON data, depending on the request (how should a client know about this?)
  3. Is it fine to do this using an action filter or should I better write e.g. a custom OWIN middleware?
yms
  • 10,361
  • 3
  • 38
  • 68
  • Other than checking for the existence of the `print` parameter in the action filter, I don't think you can do that in the WebApiConfig.cs (ie: register the action filter only when `print` param is there). As for the filestream, I'd say as long as you are returning the correct content headers, the client should know fine and react accordingly - http://stackoverflow.com/questions/9541351/returning-binary-file-from-controller-in-asp-net-web-api – Francis Ducharme Apr 07 '15 at 13:31

1 Answers1

0

Good practice to accomplish that is to create a custom http handler / owin middleware. It's better to have different handlers/middlewares for different types of responses instead of "hidden logic" somewhere in your code.

You have a WebApi which returns a JSON data by default, but in some cases it returns a PDF file. For me it sounds strange. With a http handler you will not have a comments which describes some fuzzy logic like:

// look for parameter ?print in the request query string
// manipulate response to return a filestream instead of json data

The names of these two components describes themselves. The HttpHandler sounds like it will handle some kind of requests and on the other hand the ActionFilter sounds to filter requests to a concrete action.

Here is a quote from MSDN about action filters:

Action filter, which wraps the action method execution. This filter can perform additional processing, such as providing extra data to the action method, inspecting the return value, or canceling execution of the action method.

Also with a middleware you will loose some kind of code coupling and make your code easier for reading and maintaining. But it depends a lot of what is your team conventions and all the business logic around that piece of code.