我从WebAPI控制器返回一个文件.Content-Disposition标头值自动设置为"attachment".例如:
性格:依恋; 文件名= "30956.pdf"; 文件名*= UTF-8''30956.pdf
当它设置为附件时,浏览器将要求保存文件而不是打开它.我想打开它.
如何将其设置为"内联"而不是"附件"?
我正在使用此方法发送文件:
public IActionResult GetDocument(int id)
{
var filename = $"folder/{id}.pdf";
var fileContentResult = new FileContentResult(File.ReadAllBytes(filename), "application/pdf")
{
FileDownloadName = $"{id}.pdf"
};
// I need to delete file after me
System.IO.File.Delete(filename);
return fileContentResult;
}
Run Code Online (Sandbox Code Playgroud)
Ash*_*Lee 55
我找到的最好方法是手动添加内容处理标头.
private IActionResult GetFile(int id)
{
var file = $"folder/{id}.pdf";
// Response...
System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
FileName = file,
Inline = displayInline // false = prompt the user for downloading; true = browser to try to show the file inline
};
Response.Headers.Add("Content-Disposition", cd.ToString());
Response.Headers.Add("X-Content-Type-Options", "nosniff");
return File(System.IO.File.ReadAllBytes(file), "application/pdf");
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*son 19
在AspNetCore和的2.0.0版本中AspNetCore.Mvc,我发现以前的答案都不可接受。对我来说,简单地省略filename参数File足以触发内联内容处置。
return File(fileStream, contentType, fileName); // attachment
return File(fileStream, contentType); // inline
Run Code Online (Sandbox Code Playgroud)
鉴于您不希望在字节数组中一次读取内存中的文件(使用各种File(byte[]...)重载或使用FileContentResult),您可以使用File(Stream, string, string)重载,其中最后一个参数指示文件将在何处下载以供下载:
return File(stream, "content/type", "FileDownloadName.ext");
Run Code Online (Sandbox Code Playgroud)
或者,您可以利用支持流式传输的现有响应类型(例如a)FileStreamResult,并自行设置内容处置.如图所示,执行此操作的规范方法FileResultExecutorBase是在操作方法中简单地在响应上设置标题:
// Set up the content-disposition header with proper encoding of the filename
var contentDisposition = new ContentDispositionHeaderValue("attachment");
contentDisposition.SetHttpFileName("FileDownloadName.ext");
Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString();
// Return the actual filestream
return new FileStreamResult(@"path\to\file", "content/type");
Run Code Online (Sandbox Code Playgroud)
您可以覆盖默认FileContentResult类,以便您可以在代码中使用它,只需进行最少的更改:
public class InlineFileContentResult : FileContentResult
{
public InlineFileContentResult(byte[] fileContents, string contentType)
: base(fileContents, contentType)
{
}
public override Task ExecuteResultAsync(ActionContext context)
{
var contentDispositionHeader = new ContentDispositionHeaderValue("inline");
contentDispositionHeader.SetHttpFileName(FileDownloadName);
context.HttpContext.Response.Headers.Add(HeaderNames.ContentDisposition, contentDispositionHeader.ToString());
FileDownloadName = null;
return base.ExecuteResultAsync(context);
}
}
Run Code Online (Sandbox Code Playgroud)
可以对以下内容执行相同的操作FileStreamResult:
public class InlineFileStreamResult : FileStreamResult
{
public InlineFileStreamResult(Stream fileStream, string contentType)
: base(fileStream, contentType)
{
}
public override Task ExecuteResultAsync(ActionContext context)
{
var contentDispositionHeader = new ContentDispositionHeaderValue("inline");
contentDispositionHeader.SetHttpFileName(FileDownloadName);
context.HttpContext.Response.Headers.Add(HeaderNames.ContentDisposition, contentDispositionHeader.ToString());
FileDownloadName = null;
return base.ExecuteResultAsync(context);
}
}
Run Code Online (Sandbox Code Playgroud)
而不是返回FileContentResultor FileStreamResult,只需返回InlineFileContentResultor InlineFileStreamResult。铁:
public IActionResult GetDocument(int id)
{
var filename = $"folder/{id}.pdf";
return new InlineFileContentResult(File.ReadAllBytes(filename), "application/pdf")
{
FileDownloadName = $"{id}.pdf"
};
}
Run Code Online (Sandbox Code Playgroud)
警告
正如makman99所指出的,不要使用ContentDisposition该类来生成标头值,因为它会在标头值中插入换行符以获得更长的文件名。
这些解决方案都不适合我。唯一对我有用的是更新后端的 Cors:
services.AddCors(o => o.AddPolicy("MyPolicy", b =>
{
b.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("Content-Disposition");
}));
Run Code Online (Sandbox Code Playgroud)
所以标题会被暴露。此后,我不需要向响应添加任何额外的标头。
如果您不想更新 Startup.cs,您可以手动允许该响应的标头:
HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
HttpContext.Response.Headers.Add("Content-Disposition", <your_header_value>);
Run Code Online (Sandbox Code Playgroud)
由于File()会忽略Content-Disposition我使用了这个:
Response.Headers[HeaderNames.ContentDisposition] = new MimeKit.ContentDisposition { FileName = fileName, Disposition = MimeKit.ContentDisposition.Inline }.ToString();
return new FileContentResult(System.IO.File.ReadAllBytes(filePath), "application/pdf");
Run Code Online (Sandbox Code Playgroud)
它有效:-)
| 归档时间: |
|
| 查看次数: |
28373 次 |
| 最近记录: |