C# 将WebAPI响应另存为PDF文件

C# 将WebAPI响应另存为PDF文件,c#,http,pdf,asp.net-core,asp.net-core-webapi,C#,Http,Pdf,Asp.net Core,Asp.net Core Webapi,我已经编写了返回文件的WebAPI GET方法,我已经检查了SoapUI,它工作得很好。现在我想调用该服务并将文件保存为本地驱动器中的PDF格式,我从该服务获得响应,但如何将响应转换为PDF格式的文件 public async Task<IActionResult> FileIndex() { try { HttpClientHandler clientHandler = new HttpClientHandler(); client

我已经编写了返回文件的WebAPI GET方法,我已经检查了SoapUI,它工作得很好。现在我想调用该服务并将文件保存为本地驱动器中的PDF格式,我从该服务获得响应,但如何将响应转换为PDF格式的文件

public async Task<IActionResult> FileIndex()
{
    try
    {
        HttpClientHandler clientHandler = new HttpClientHandler();

        clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };

        HttpClient client = new HttpClient(clientHandler);
        HttpResponseMessage response = await client.GetAsync("https://test-server/api/files");

        if (response.IsSuccessStatusCode)
        {
            var output= await response.Content.ReadAsAsync<byte[]>();
            System.IO.File.WriteAllBytes(@"E:\testpdf.pdf", output);
        }
    }
    catch (Exception ex)
    {
    }

    return View();
}

你可以用这个例子来解释你的需要

public void GeneratePdf(string htmlPdf)
{
   var pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
   var htmlparser = new HTMLWorker(pdfDoc);
   using (var memoryStream = new MemoryStream())
   {
       var writer = PdfWriter.GetInstance(pdfDoc, memoryStream);
       pdfDoc.Open();

       htmlparser.Parse(new StringReader(htmlPdf));
       pdfDoc.Close();

       byte[] bytes = memoryStream.ToArray();
       File.WriteAllBytes(@"C:\file.pdf", bytes);

       memoryStream.Close();
}

}

你可以用这个例子来解释你的需要

public void GeneratePdf(string htmlPdf)
{
   var pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
   var htmlparser = new HTMLWorker(pdfDoc);
   using (var memoryStream = new MemoryStream())
   {
       var writer = PdfWriter.GetInstance(pdfDoc, memoryStream);
       pdfDoc.Open();

       htmlparser.Parse(new StringReader(htmlPdf));
       pdfDoc.Close();

       byte[] bytes = memoryStream.ToArray();
       File.WriteAllBytes(@"C:\file.pdf", bytes);

       memoryStream.Close();
}

}

我认为您的主要问题是试图在
FileIndex()
方法中使用
Microsoft.AspNet.WebApi.Client
中的
ReadAsAsync

var output=wait response.Content.ReadAsAsync();
这是为了处理JSON响应。有一些链接错误地声称,通过在
WebApiConfig.cs
中添加a行,您可以使用
应用程序/octet流
响应,例如:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(新的MediaTypeHeaderValue(“应用程序/八位字节流”);
我相信这个建议是有缺陷的,我从来没能让它发挥作用。如果项目中有该行,则应将其删除,并在
FileIndex()
方法中使用以下内容:

var output=wait response.Content.ReadAsByteArrayAsync();
下面是一个完整的控制台应用程序,它使用Web API方法中的
application/pdf
流并将其保存到磁盘(在TestClient.exe文件旁边的TestClient/bin/Debug文件夹中):

使用System.Net.Http;
使用System.Threading.Tasks;
命名空间测试客户端
{
类主类
{
公共静态异步任务FileIndex()
{
HttpClientHandler clientHandler=新的HttpClientHandler();
var requestUri=”http://localhost:8080/api/files";
//var requestUri=”https://test-server/api/files";
//clientHandler.ServerCertificateCustomValidationCallback=
//(发送方、证书、链、sslPolicyErrors)=>{return true;};
HttpClient=新的HttpClient(clientHandler);
HttpResponseMessage response=wait client.GetAsync(requestUri);
if(响应。IsSuccessStatusCode)
{
var output=await response.Content.ReadAsByteArrayAsync();
//var path=@“E:\testpdf.pdf”;
var path=@“testpdf.pdf”;
System.IO.File.writealBytes(路径,输出);
}
}
公共静态void Main(字符串[]args)
{
FileIndex().Wait();
}
}
}
下面是我实现的一个控制器,它演示了如何使用正确的MIME类型和其他元数据信息将PDF文件返回到客户端:

使用系统;
使用System.IO;
Net系统;
使用System.Net.Http;
使用System.Net.Http.Header;
使用System.Web;
使用System.Web.Mvc;
命名空间TestServer.Controllers
{
公共类FileController:System.Web.Http.ApicController
{
[授权]
[HttpGet]
公共HttpResponseMessage Get()
{
尝试
{
var fileName=“testpdf.pdf”;
//其中“~/”是Web API服务器项目的根文件夹。。。
var localFilePath=HttpContext.Current.Server.MapPath(“~/”+文件名);
var fileInfo=newfileinfo(localFilePath);
var结果=新的HttpResponseMessage(HttpStatusCode.OK);
//警告:不要在此处使用IDisPobles或使用(){}块。
//IDisPobles需要在客户端下载期间存在。
result.Content=newbytearraycontent(File.ReadAllBytes(localFilePath));
result.Content.Headers.ContentDisposition=新的ContentDispositionHeaderValue(“附件”);
result.Content.Headers.ContentDisposition.FileName=文件名;
result.Content.Headers.ContentDisposition.CreationDate=fileInfo.CreationTimeUtc;
result.Content.Headers.ContentDisposition.ModificationDate=fileInfo.LastWriteTimeUtc;
result.Content.Headers.ContentDisposition.ReadDate=fileInfo.LastAccessTimeUtc;
result.Content.Headers.ContentLength=fileInfo.Length;
result.Content.Headers.ContentType=新的MediaTypeHeaderValue(“应用程序/pdf”);
返回结果;
}
捕获(例外情况除外)
{
//使用诸如Serilog之类的适当工具在此处记录异常。。。
Console.WriteLine(例如ToString(),例如Message);
}
返回新的HttpResponseMessage(HttpStatusCode.Gone);
}
}
}

希望这有帮助

我认为您的主要问题是试图在
FileIndex()
方法中使用
Microsoft.AspNet.WebApi.Client
中的
ReadAsAsync

var output=wait response.Content.ReadAsAsync();
这是为了处理JSON响应。有一些链接错误地声称,通过在
WebApiConfig.cs
中添加a行,您可以使用
应用程序/octet流
响应,例如:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(新的MediaTypeHeaderValue(“应用程序/八位字节流”);
我相信这个建议是有缺陷的,我从来没能让它发挥作用。如果项目中有该行,则应将其删除,并在
FileIndex()
方法中使用以下内容:

var output=wait response.Content.ReadAsByteArrayAsync();
下面是一个完整的控制台应用程序,它使用Web API方法中的
application/pdf
流并将其保存到磁盘(在TestClient.exe文件旁边的TestClient/bin/Debug文件夹中):

使用System.Net.Http;
使用System.Threading.Tasks;
命名空间测试客户端
{
类主类
{
公共静态异步任务FileIndex()