简体   繁体   中英

MVC Return File Mime Type and Global Filter issue

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() ?

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;
        }        
        
        // ...
    }
    
    // ...        
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM