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