C#无法将XML作为附件下载。
C#无法将XML作为附件下载。
在常规的MVC控制器中,我们可以使用FileContentResult
来输出pdf。\n
public FileContentResult Test(TestViewModel vm) { var stream = new MemoryStream(); //... 将内容添加到流中。 return File(stream.GetBuffer(), "application/pdf", "test.pdf"); }
\n但是如何将其改为ApiController
呢?\n
[HttpPost] public IHttpActionResult Test(TestViewModel vm) { //... return Ok(pdfOutput); }
\n
\n以下是我的尝试,但似乎不起作用。\n
[HttpGet] public IHttpActionResult Test() { var stream = new MemoryStream(); //... var content = new StreamContent(stream); content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); content.Headers.ContentLength = stream.GetBuffer().Length; return Ok(content); }
\n在浏览器中显示的返回结果是:\n{\"Headers\":[{\"Key\":\"Content-Type\",\"Value\":[\"application/pdf\"]},{\"Key\":\"Content-Length\",\"Value\":[\"152844\"]}]}\n
\n还有一个类似的SO帖子:Returning binary file from controller in ASP.NET Web API。它讨论了如何输出现有文件。但是我无法使用流使其工作。\n有什么建议吗?
C#无法将XML作为附件下载的原因是代码中没有正确设置响应的内容类型和文件名。解决方法是使用HttpResponseMessage
类来设置响应的内容,包括文件内容、文件名和文件类型。
在控制器代码中,首先获取文件的路径,然后创建一个HttpResponseMessage
对象,并将文件内容作为响应的内容进行设置。接着设置响应的内容类型为"application/octet-stream",并设置响应的文件名为文件路径的文件名部分。最后,将文件内容的长度作为响应的内容长度进行设置,并返回该响应对象。
在视图的HTML标记中,通过点击事件来触发下载文件的操作。在点击事件中,使用window.location.href
方法来进行页面跳转,并指定跳转的URL为控制器中的下载文件的方法。同时,在页面中也提供了一个链接,通过点击该链接同样可以触发下载文件的操作。
需要注意的是,代码中使用的FileStream
是用于从服务器上的现有文件中读取数据的流,而不是MemoryStream
。如果使用MemoryStream
,则无法正确下载文件。
以上就是C#无法将XML作为附件下载的原因和解决方法的整理。这个问题的解决方法主要是通过设置响应的内容类型和文件名来实现文件下载。
问题:C#无法将XML文件作为附件下载的原因和解决方法
在上述代码中,如果要返回IHttpActionResult,可以按以下方式实现:
[HttpGet]
public IHttpActionResult Test()
{
var stream = new MemoryStream();
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(stream.GetBuffer())
};
result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
{
FileName = "test.pdf"
};
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
var response = ResponseMessage(result);
return response;
}
这段代码是用于将XML文件作为附件下载的示例。它首先创建一个MemoryStream对象来存储XML文件的内容。然后,通过创建HttpResponseMessage对象,并将其Content属性设置为ByteArrayContent对象来将XML内容作为字节数组添加到响应中。接下来,设置Content-Disposition标头以指示响应应该被视为附件,并设置文件名为"test.pdf"。最后,设置Content-Type标头以指示响应的内容类型为application/octet-stream。
解决方法:
要将XML文件作为附件下载,需要使用HttpResponseMessage对象和ByteArrayContent对象来构建响应。在构建HttpResponseMessage对象时,需要设置Content属性为ByteArrayContent对象,并设置Content-Disposition标头和Content-Type标头来指示附件的文件名和内容类型。然后,将HttpResponseMessage对象包装在IHttpActionResult中返回。
在上述代码中,如果使用stream.GetBuffer()方法获取字节数组,需要使用ByteArrayContent的特定构造函数来指定字节数组的实际大小。这是因为内部缓冲区数组的长度可能大于实际内容的长度,因此需要指定内容长度。
上述代码提供了一个简单的实现示例,但也可以根据具体需求调用自定义的IHttpActionResult方法来实现相同的功能。
请注意,如果你认为这个答案有问题,请指出原因,以便改进回答。
问题:C#无法将XML作为附件下载的原因及解决方法
在这段代码中,将StreamContent
作为Content
返回,我可以使用ByteArrayContent
来使其正常工作。
[HttpGet] public HttpResponseMessage Generate() { var stream = new MemoryStream(); // 处理流。 var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(stream.ToArray()) }; result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = "CertificationCard.pdf" }; result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); return result; }
如果上半部分回答了你的问题,请只将其作为答案发布。下半部分似乎是一个不同的问题-请为此发布一个新问题。
嗨,谢谢分享,有一个简单的问题(我猜)。我有一个接收httpresponsemessage的C#前端。如何提取streamcontent并使其可用,以便用户可以将其保存到磁盘或其他地方(我可以获得实际的文件)?谢谢!
我试图下载一个自动生成的Excel文件。使用stream.GetBuffer()总是返回一个损坏的Excel文件。如果改用stream.ToArray(),文件就可以正常生成。希望这对某人有所帮助。
这是因为MemoryStream.GetBuffer()
实际上返回了MemoryStream的缓冲区,它通常比流的内容要大(以使插入操作高效)。MemoryStream.ToArray()
返回截断为内容大小的缓冲区。
非常感谢。这也是我的问题。
因为我要返回一个大文件,所以我需要使用流来缓冲内容,而不是将整个文件预先读入内存。我发现这个答案在另一个帖子中很有帮助:stackoverflow.com/a/9549889/540061
谢谢,这也是我的情况。我编辑了这个答案,因为我没有看到有实际的理由为什么有人想要获取实际的底层数组,它可能比保存在MemoryStream中的实际数据更大。
请停止这样做。这种对MemoryStream的滥用会导致不可扩展的代码,完全忽略了流的目的。想想为什么不把所有东西都公开为byte[]
缓冲区?你的用户很容易用尽内存来运行你的应用程序。
MemoryStream的替代方案是什么?
应该使用小型(通常为~4 KB)缓冲区将流传输到另一个流中。.NET方便地提供了一个方法:Stream.CopyTo
除非网页在渲染时使用分块,否则所有数据都会在内存中。
这对我不起作用。它确实将PDF作为字节数组返回到前端,但当我尝试打开它时,出现错误“无法加载PDF文档”。
只要使用ByteArrayContent(Byte[], Int32, Int32)
构造函数指定实际大小,你就可以使用stream.GetBuffer()
: new ByteArrayContent(stream.GetBuffer(), 0, checked((int)stream.Length))
。 这将更节省内存,因为ToArray()
实际上是复制内部缓冲区的内容。
对于存储在路径中的文件,这个对我有用。
答案不完整。在哪里下载文件?如何从HttpResponseMessage中提取文件以供用户下载。
原文链接:https://stackoverflow.com/questions/66996464/66996547#66996547