c# - 请求和处理包含字节 [] 文件的 Web-API 响应的最佳方式?

标签 c# asp.net-web-api azure-storage

我正在尝试从我的 REST API 返回一个 pdf 文件,并已将 ReportController 添加到我的 Controller 集合中,如下所示。

public class ReportController : ApiController
{
    public HttpResponseMessage Get(int id)
    {
        var result = new HttpResponseMessage(HttpStatusCode.OK);
        string fileName = id.ToString();

        MemoryStream memoryStream = GetStreamFromBlob(fileName);
        result.Content = new ByteArrayContent(memoryStream.ToArray());
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");

        return result;
    }
}

其他 Controller 都工作正常,但这是第一个设置为返回 HttpResponseMessage 而不是可序列化对象或对象集合的 Controller 。

但是我很难从客户端使用它。已经尝试了多个版本的代码来执行此操作,但是 Controller 代码从未被命中,而且似乎很少有成功调用此方法的完整示例。以下是我当前的版本:-

public async Task<string> GetPdfFile(int id)
{
    string fileName = string.Format("C:\\Code\\PDF_Client\\{0}.pdf", id);

    using (HttpClient proxy = new HttpClient())
    {
        string url = string.Format("http://localhost:10056/api/report/{0}", id);
        HttpResponseMessage reportResponse = await proxy.GetAsync(url);  //****
        byte[] b = await reportResponse.Content.ReadAsByteArrayAsync();
        System.IO.File.WriteAllBytes(fileName, b);
    }
    return fileName;
}

然而 **** 行失败并显示消息 No connection could be made because the target machine actively refused it 127.0.0.1:10056

正如我所说,http://localhost:10056/api/ 中的其他 Controller 工作正常。

这是从 WEBAPI 服务器方法获取文件的正确方法吗?

对于代码的其他方面,您是否有任何建议可以更好,例如使用 await/async,或者 Controller 返回文件的更好方法?

最佳答案

我遇到了同样的问题,想将 PDF 写入 ApiController 操作的输出。

此链接帮助我:http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

我编写了自己的 MediaTypeFormatter,用于从字节数组编写 PDF。

public class PdfFormatter : MediaTypeFormatter
{
    #region Constants and Fields

    private const int ChunkSizeMax = 1024 * 10;

    #endregion

    #region Constructors and Destructors

    public PdfFormatter()
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/pdf"));
    }

    #endregion

    #region Public Methods

    public override bool CanReadType(Type type)
    {
        return false; // can't read any types
    }

    public override bool CanWriteType(Type type)
    {
        return type == typeof(byte[]);
    }

    public override Task WriteToStreamAsync(
        Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        Task t = new Task(() => WritePdfBytes(value, writeStream));
        t.Start();
        return t;
    }

    #endregion

    #region Methods

    private static void WritePdfBytes(object value, Stream writeStream)
    {
        byte[] buffer = value as byte[];
        int offset = 0;

        while (offset < buffer.Length)
        {
            int chunkSize = Math.Min(buffer.Length - offset, ChunkSizeMax);
            writeStream.Write(buffer, offset, chunkSize);
            offset += chunkSize;
        }
    }

    #endregion
}

然后,我像这样在 Global.asax 中注册了这个格式化程序:

private void SetupFormatters()
{
    GlobalConfiguration.Configuration.Formatters.Add(new PdfFormatter());
}

我的 ApiController Get 方法的相关部分如下所示:

public HttpResponseMessage Get(string url, string title)
{
    byte[] pdfBytes;

    /* generate the pdf into pdfBytes */

    string cleanTitle = new Regex(@"[^\w\d_-]+").Replace(title, "_");
    string contentDisposition = string.Concat("attachment; filename=", cleanTitle, ".pdf");
    HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, pdfBytes, MediaTypeHeaderValue.Parse("application/pdf"));
    response.Content.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse(contentDisposition);

    return response;
}

关于c# - 请求和处理包含字节 [] 文件的 Web-API 响应的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19991984/

相关文章:

c# - 身份框架为用户创建一个新密码(没有密码)

c# - 如何在多部分/表单数据请求的请求正文中记录文件内容

python - 使用文件路径的csv从azure blob容器下载数百万个文件python

c# - 在 C# SDK 中使用存储连接字符串通过 URI 访问 blob

c# - Xamarin 安卓 : Shared MonoRuntime error

c# - 从 BackgroundWorker C# 调用的 CoInitialize

c# - 发送批量电子邮件时出错 "An asynchronous call is already in progress. It must be completed or canceled before you can call this method"

c# - WPF:无法让我控制焦点

c# - 自托管 Web Api C# 与 Windows 窗体错误

python - Azure 函数 (python) 将输出写入输出 blob 路径的动态命名