我正在使用ASP开发一个web服务。NET MVC的新WebAPI将提供二进制文件,主要是。cab和。exe文件。

下面的控制器方法似乎可以工作,这意味着它返回了一个文件,但它将内容类型设置为application/json:

public HttpResponseMessage<Stream> Post(string version, string environment, string filetype)
{
    var path = @"C:\Temp\test.exe";
    var stream = new FileStream(path, FileMode.Open);
    return new HttpResponseMessage<Stream>(stream, new MediaTypeHeaderValue("application/octet-stream"));
}

还有更好的办法吗?


当前回答

您可以尝试下面的代码片段

httpResponseMessage.Content.Headers.Add("Content-Type", "application/octet-stream");

希望它对你有用。

其他回答

您正在使用的重载设置序列化格式化程序的枚举。你需要像这样显式地指定内容类型:

httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

对于任何在使用接受答案中的方法下载相当大的文件时,API被多次调用的问题,请将响应缓冲设置为true System.Web.HttpContext.Current.Response.Buffer = true;

这确保在将整个二进制内容发送到客户端之前,在服务器端对其进行了缓冲。否则,您将看到多个请求被发送到控制器,如果您没有正确处理它,文件将被损坏。

虽然建议的解决方案工作得很好,但还有另一种方法可以从控制器返回一个字节数组,并正确格式化响应流:

在请求中,设置报头“Accept: application/octet-stream”。 服务器端,添加一个媒体类型格式化器来支持此mime类型。

不幸的是,WebApi不包括任何用于“应用程序/八字节流”的格式化程序。在GitHub上有一个实现:BinaryMediaTypeFormatter(有一些小的调整,使其适用于webapi 2,方法签名更改)。

你可以在全局配置中添加这个格式化器:

HttpConfiguration config;
// ...
config.Formatters.Add(new BinaryMediaTypeFormatter(false));

如果请求指定了正确的Accept报头,WebApi现在应该使用BinaryMediaTypeFormatter。

我更喜欢这个解决方案,因为动作控制器返回字节[]更适合测试。不过,如果你想返回“application/octet-stream”以外的其他内容类型(例如“image/gif”),另一种解决方案允许你进行更多的控制。

对于使用。net Core的用户:

你可以在API控制器方法中使用IActionResult接口,就像这样。

[HttpGet("GetReportData/{year}")]
public async Task<IActionResult> GetReportData(int year)
{
    // Render Excel document in memory and return as Byte[]
    Byte[] file = await this._reportDao.RenderReportAsExcel(year);

    return File(file, "application/vnd.openxmlformats", "fileName.xlsx");
}

这个例子很简单,但应该能让人理解。在。net Core中,这个过程比以前的。net版本要简单得多——即不需要设置响应类型、内容、报头等。

当然,文件和扩展名的MIME类型也取决于个人需求。

参考:@NKosi的回复

您可以尝试下面的代码片段

httpResponseMessage.Content.Headers.Add("Content-Type", "application/octet-stream");

希望它对你有用。