C# 返回HttpResponseMessage的控制器未正确设置内容类型

C# 返回HttpResponseMessage的控制器未正确设置内容类型,c#,asp.net-mvc,httpresponsemessage,C#,Asp.net Mvc,Httpresponsemessage,我在控制器中有以下代码,用于返回一个流,该流是一个Excel文件,可在客户端下载: HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); MemoryStream memStream = ReportExporter.ExportReport(analystReport); response.Content = new StreamContent(memStream); response.Conte

我在控制器中有以下代码,用于返回一个流,该流是一个Excel文件,可在客户端下载:

HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
MemoryStream memStream = ReportExporter.ExportReport(analystReport);

response.Content = new StreamContent(memStream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = saveAsFileName;

return response;
当我在客户端发出请求时,它只会返回响应消息的包装器:

StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Content-Type: application/octet-stream
  Content-Disposition: attachment; filename=.xlsx
}
我相信这可能是由于标题以文本形式返回,因为这是我在Chrome中看到的:

Content-Type:text/html; charset=utf-8   
我尝试了各种各样的方法,弄不清楚这里发生了什么

试试这个解决方案:

// Copy file to byte array
byte[] file = new byte[memStream.Length];
memStream.Read(file, 0, file.Length);

// Send file
Response.ContentType = "application/octet-stream";
Response.AddHeader("content-disposition", "inline;filename=" + saveAsFileName);
Response.Buffer = true;
Response.Clear();
Response.BinaryWrite(file);
Response.End();

// Return success
return new HttpStatusCodeResult(HttpStatusCode.OK);
Response
是一个
Controller
属性,因此您不需要创建任何
HttpResponseMessage
对象。

尝试以下解决方案:

// Copy file to byte array
byte[] file = new byte[memStream.Length];
memStream.Read(file, 0, file.Length);

// Send file
Response.ContentType = "application/octet-stream";
Response.AddHeader("content-disposition", "inline;filename=" + saveAsFileName);
Response.Buffer = true;
Response.Clear();
Response.BinaryWrite(file);
Response.End();

// Return success
return new HttpStatusCodeResult(HttpStatusCode.OK);

Response
是一个
Controller
属性,因此您不需要创建任何
HttpResponseMessage
对象。

有许多方法可以解决此问题,但我将向您展示我的方法。您可以只执行FileStreamResult,而不是HttpResponseMessage。您不需要实例化HttpResponseMessage,它已经是控制器方法的一部分了。这就是我开始尝试修复您的代码的方式。请记住改用FileStreamResult

    public FileStreamResult DownloadExcel(???analystReport????)
    {
        MemoryStream memStream = ReportExporter.ExportReport(analystReport);

        return new FileStreamResult(memStream , "application/vnd.ms-excel", saveAsFileName);
    }

有很多方法可以解决这个问题,但我会告诉你我的方法。您可以只执行FileStreamResult,而不是HttpResponseMessage。您不需要实例化HttpResponseMessage,它已经是控制器方法的一部分了。这就是我开始尝试修复您的代码的方式。请记住改用FileStreamResult

    public FileStreamResult DownloadExcel(???analystReport????)
    {
        MemoryStream memStream = ReportExporter.ExportReport(analystReport);

        return new FileStreamResult(memStream , "application/vnd.ms-excel", saveAsFileName);
    }


响应的类型是什么?
?很抱歉,有一点代码丢失,请将其添加回,这是一个HTTPResponseMessage,您通常也应该包含控制器方法声明。它确定/指示代码所需的接口。事实上,您看到的是
HttpResponseMessage
的序列化表示,这意味着您对它的实例化不正确、返回不正确或两者都不正确。请按照@montewhizdoh指示的方式显示操作方法签名。@montewhizdoh您可以从WebAPI控制器返回
HttpResponseMessage
,但不能从MVC返回,或者至少根据MVC版本返回。使用MVC 6,您可以。什么类型的
响应
?很抱歉,有一点代码丢失,请重新添加,这是一个HTTPResponseMessage,您通常也应该包括控制器方法声明。它确定/指示代码所需的接口。事实上,您看到的是
HttpResponseMessage
的序列化表示,这意味着您对它的实例化不正确、返回不正确或两者都不正确。请按照@montewhizdoh指示的方式显示操作方法签名。@montewhizdoh您可以从WebAPI控制器返回
HttpResponseMessage
,但不能从MVC返回,或者至少根据MVC版本返回。使用MVC6,您可以“注意最后一行,它未经测试”-是的,您不能像那样以ASCII字符串形式返回二进制Excel文件。您如何将memStream转换为字符串?错误的问题。问题是“为什么”。它是一个二进制文件,所以您应该将其作为二进制文件使用。现在还不清楚为什么你认为把它当作字符串就能解决这个问题。好的,我不应该这么懒和不清楚。我切换到一个更原生的接口。谢谢“注意最后一行,它未经测试”-是的,你不能像那样以ASCII字符串的形式返回二进制Excel文件。你如何将memStream转换为字符串?错误的问题。问题是“为什么”。它是一个二进制文件,所以您应该将其作为二进制文件使用。现在还不清楚为什么你认为把它当作字符串就能解决这个问题。好的,我不应该这么懒和不清楚。我切换到一个更原生的接口。谢谢不知道为什么会被否决?这解决了我的问题,虽然我稍微改变了字节位的转换,因为您的版本给了我正确的字节数,但它给了我一个巨大的空列表。我使用了:byte[]bytes=memStream.ToArray();那么,您的代码的其余部分就可以完美地工作了,非常感谢:)不知道为什么会被否决?这解决了我的问题,虽然我稍微改变了字节位的转换,因为您的版本给了我正确的字节数,但它给了我一个巨大的空列表。我使用了:byte[]bytes=memStream.ToArray();那么剩下的代码就可以完美地工作了,非常感谢:)