加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – MVC 6 WebAPI返回序列化的HttpResponseMessage而不是

发布时间:2020-12-15 20:50:56 所属栏目:asp.Net 来源:网络整理
导读:我正在尝试让我的ASP.Net 5 MVC 6 WebAPI项目输出一个文件,以响应HttpGET请求. 该文件来自Azure Files共享,但它可以是包含二进制文件的任何流. 在我看来,MVC序列化响应对象,并返回结果JSON,而不是返回响应对象本身. 这是我的控制器方法: [HttpGet] [Route("
我正在尝试让我的ASP.Net 5 MVC 6 WebAPI项目输出一个文件,以响应HttpGET请求.

该文件来自Azure Files共享,但它可以是包含二进制文件的任何流.

在我看来,MVC序列化响应对象,并返回结果JSON,而不是返回响应对象本身.

这是我的控制器方法:

[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;
        }
    }

AzureFilesClient上的GetFileStream方法在此处,但流源可以是包含二进制文件内容的任何内容:

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;
        }
    }

编辑:以下是JSON响应的示例:

{
    "Version": {
        "Major": 1,"Minor": 1,"Build": -1,"Revision": -1,"MajorRevision": -1,"MinorRevision": -1
    },"Content": {
        "Headers": [
            {
                "Key": "Content-Type","Value": [
                    "application/octet-stream"
                ]
            },{
                "Key": "Content-Disposition","Value": [
                    "attachmentx; filename="samplefile.docx""
                ]
            }
        ]
    },"StatusCode": 200,"ReasonPhrase": "OK","Headers": [],"RequestMessage": null,"IsSuccessStatusCode": true
}

解决方法

在结合阅读文档以及一些反复试验之后,问题就解决了.

Azure部分是使用nuGet包“WindowsAzure.Storage”(4.4.1预览版)制作的

首先是获得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参数设置为动态,而不是像这样静态.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读