我试图让我的ASP.Net 5 MVC 6 WebAPI项目输出一个文件,以响应HttpGET请求。
该文件来自Azure Files共享,但它可以是包含二进制文件的任何流。
在我看来,MVC序列化响应对象,并返回生成的JSON,而不是返回响应对象本身。
这是我的控制器方法:
var data = $('#example').dataTable().fnGetData();
AzureFilesClient上的GetFileStream方法在这里,尽管流源可以是包含二进制文件内容的任何内容:
[HttpGet]
[Route("GetFile")]
public HttpResponseMessage GetFile(string Username, string Password, string FullName)
{
var client = new AzureFilesClient.AzureFilesClient(Username, Password);
Stream azureFileStream = client.GetFileStream(FullName).Result;
var fileName = Path.GetFileName(FullName);
using (HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK))
{
response.Content = new StreamContent(azureFileStream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileName };
return response;
}
}
编辑:以下是JSON响应的示例:
public async Task<Stream> GetFileStream(string fileName)
{
var uri = new Uri(share.Uri + "/" + fileName);
var file = new CloudFile(uri, credentials);
using (var stream = new MemoryStream())
{
await file.DownloadToStreamAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
}
答案 0 :(得分:6)
在阅读文档和一些试错之后,问题已经解决了。
Azure部分是使用nuGet包“WindowsAzure.Storage”(4.4.1-preview)制作的
首先获得JSON序列化的输出。 这需要返回自定义操作结果。
using Microsoft.AspNet.Mvc;
using System.IO;
using System.Threading.Tasks;
public class FileResultFromStream : ActionResult
{
public FileResultFromStream(string fileDownloadName, Stream fileStream, string contentType)
{
FileDownloadName = fileDownloadName;
FileStream = fileStream;
ContentType = contentType;
}
public string ContentType { get; private set; }
public string FileDownloadName { get; private set; }
public Stream FileStream { get; private set; }
public async override Task ExecuteResultAsync(ActionContext context)
{
var response = context.HttpContext.Response;
response.ContentType = ContentType;
context.HttpContext.Response.Headers.Add("Content-Disposition", new[] { "attachment; filename=" + FileDownloadName });
await FileStream.CopyToAsync(context.HttpContext.Response.Body);
}
}
现在获取从Azure文件共享(或任何其他异步流源)流式传输的二进制数据
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.File;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
public async Task<Stream> GetFileStreamAsync(string fileName)
{
var uri = new Uri(share.Uri + "/" + fileName);
var file = new CloudFile(uri, credentials);
// Note: Do not wrap the stream variable in a Using, since it will close the stream too soon.
var stream = new MemoryStream();
await file.DownloadToStreamAsync(stream);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
最后是控制器代码。注意使用IActionResult接口。
[HttpGet]
[Route("GetFile")]
public async Task<IActionResult> GetFile(string username, string password, string fullName)
{
var client = new AzureFilesClient.AzureFilesClient(username, password);
Stream stream = await client.GetFileStreamAsync(fullName);
string fileName = Path.GetFileName(fullName);
return new CustomActionResults.FileResultFromStream(fileName, stream, "application/msword");
}
注意:此示例仅用于Word文件,您可能希望将ContentType参数设置为动态,而不是像这样静态。