在Web响应中返回PDF内容,如何在本地保存?

时间:2017-08-23 13:36:50

标签: c# .net pdf webclient

我通过API获取网络响应,该文件将文件转换(在本例中为Powerpoint演示文稿)。

我确实在一个字符串中得到了响应,但是当把这个字符串保存到一个文件或一个流(最后还是保存在一个文件中)时,我总是得到一个空白文件,它的大小总是远远超过0字节虽然。

这是调用API的类:

public class CloudConvert
{

    private string apiKey;
    private static object ProcessResponse;

    public CloudConvert(string apiKey)
    {
        this.apiKey = apiKey;
    }

    public async Task<string> Convert(string inputFormat, string outputFormat, string fileUrl)
    {
        var processUrl = await CreateProcess(inputFormat, outputFormat);
        return await Upload(processUrl, fileUrl, outputFormat);
    }

    private async Task<string> CreateProcess(string inputFormat, string outputFormat)
    {
        var request = new
        {
            apikey = apiKey,
            inputformat = inputFormat,
            outputformat = outputFormat
        };

        var json = await PostJson("https://api.cloudconvert.com/process", request);

        dynamic obj = JObject.Parse(json);
        ProcessResponse = obj;
        return "https:" + obj.url;
    }

    private static async Task<string> Upload(string processUrl,
        string fileUrl, string outputFormat)
    {
        var request = new
        {
            input = "download",
            file = fileUrl,
            outputformat = outputFormat,
            download = "false",
            wait = "true",
            save = "false"
        };

        return await PostJson(processUrl, request);
    }


    private static async Task<string> PostJson(string url, object data)
    {
        var parameters = JsonConvert.SerializeObject(data);

        using (var wc = new WebClient())
        {
            wc.Headers[HttpRequestHeader.ContentType] = "application/json";

            try
            {
                return await wc.UploadStringTaskAsync(url, "POST", parameters);
            }
            catch (WebException ex)
            {
                return string.Empty;
            }
        }
    }

}

我是如何调用它的:

Task<string> task = Task.Run(async () =>
{
    return await cloudConvert.Convert("ppt", "pdf", "http://host.com/myfile.ppt");
});

//I have the PDF in the response, as a string.
var pdfContent = task.Result;

//I think it's here that I'm not handling the resulting string 
//properly, ending in a blank file. I've tried writing it to a local file as well, same issue.
using (MemoryStream stream = new MemoryStream())
{
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(pdfContent);
    writer.Flush();
    stream.Seek(0, SeekOrigin.Begin);
    //This below is something that saves to an Azure storage container...
    //filePath = fileStorage.SaveFile($"{fileGeneratedName}.pdf", stream);

    //But this fails as well. Blank file 
    using (FileStream fs = new FileStream(@"c:\tmp\output.pdf", FileMode.OpenOrCreate))
    {
        stream.CopyTo(fs);
        fs.Flush();
    }
}

因此,无论我如何尝试保存返回的内容,我的编码似乎都是错误的。我注意到生成的空白文件总是与输入的Powerpoint演示文稿具有相同的页数。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

让你的转换函数返回一个HttpResponseMessage:

public async Task<HttpResponseMessage> convert()

转换为内存流,然后:

var result = new HttpResponseMessage(HttpStatusCode.OK)
{
     Content = new ByteArrayContent(outStream.GetBuffer(),0,(int)outStream.Length)
};
result.Content.Headers.ContentDisposition =
         new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
         {
              FileName = fname
         };
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return result;