Home > Mobile >  MVC Return File Mime Type and Global Filter issue
MVC Return File Mime Type and Global Filter issue

Time:08-18

I have a MVC application (.Net FrameWork 4.8).

I have a Global Filter defined like this :

    protected void Application_Start()
    {
        ...
        GlobalFilters.Filters.Add(new Shared.Filters.WetFilter());
        ...
    }

And a part of my filter here :

public class WetFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.HttpContext.Response.ContentType == "text/html")
        {
            // do stuff here
        }
    }

In my controller, I return a file :

    public async Task<ActionResult> DownloadFile(int id)
    {
        // some stuff here
        return File(file.Data, "application/pdf", file.Name);
    }

The issue is, the return File specify mime type, but the file is altered by my global filter. The mime type is always text/html.

If I return the file the old way, it works as expected; ie, the global filter got the right mime type and doesn't alter the content.

    protected void DownloadFile(string fileName, byte[] data, string mimeType)
    {
        Response.ClearContent();
        Response.ClearHeaders();
        Response.Buffer = false;
        Response.ContentType = mimeType;
        Response.AppendHeader("Content-Length", data.Length.ToString());
        Response.AppendHeader("Content-Disposition", string.Format("attachment; filename=\"{0}\"", Server.UrlEncode(fileName)));
        Response.BinaryWrite(data);
        Response.Flush();

        System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest();
    }

My question, why my global filter doesn't get the mime type specified by return File()?

CodePudding user response:

In the return File scenario, the actual content type hasn't yet been set to the HttpContext when the action filter executes.

In that case just inspect the filterContext.Result.
The code below will find the expected application/pdf content type for that returned file.

public class WetFilter : ActionFilterAttribute
{    
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // ...
        
        var fileResult = filterContext.Result as FileResult;
        if (fileResult != null)
        {
            var contentType = fileResult.ContentType;
        }        
        
        // ...
    }
    
    // ...        
}
  • Related