首页 > 解决方案 > PostAsync 适用于 xml 但不适用于 pdf 文件

问题描述

我不知道出了什么问题以及为什么这篇文章Error 500只返回 pdf 文件,它可以正常使用 xml 文件。我尝试以多种方式更改标头值,它始终响应相同的错误:

服务器指责:

MultipartException: Failed to parse multipart servlet request; nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Stream ended unexpectedly

内容:

public class UploadRequest
{
    public byte[] fileToUpload { get; set; }
    public string fileType { get; set; }
    public string fileReference { get; set; }
    public string issueDate { get; set; }
    public string userId { get; set; }
    public string headerValue { get; set; }

    public string fileName { get; set; }

    public UploadRequest(string fileName, byte[] fileToUpload, String fileType, String fileReference, 
        String issueDate, String userId, String headerValue)
    {
        this.fileName = fileName;
        this.fileToUpload = fileToUpload;
        this.fileType = fileType;
        this.fileReference = fileReference;
        this.issueDate = issueDate;
        this.userId = userId;
        this.headerValue = headerValue;
    }

    public MultipartFormDataContent getFormContent(){

      var fileToUploadContent = new ByteArrayContent(fileToUpload, 0, fileToUpload.Length);            
      fileToUploadContent.Headers.Add("content-type", "application/" + headerValue); // 'pdf' or 'xml'            

      return new MultipartFormDataContent
        {
            { fileToUploadContent, "file", fileName},
            { new StringContent(fileType), "fileType"},
            { new StringContent(fileReference), "fileReference"},
            { new StringContent(issueDate), "issueDate"},
            { new StringContent(userId), "userId"}
        };
    }
}

邮寄方式:

public class Upload
{
   private HttpClient client = new HttpClient();
   private string urlBase = "https://xxxxxxxx-xx.xx.us10.hana.xxxxx.com/file/upload/ImportDeclaration/";

  public async void sendFilesWs(UploadRequest requestData, Int64 ?processNumber)
  {
    try
    {
      client.BaseAddress = new Uri(urlBase);
      client.DefaultRequestHeaders.Add("Authorization", "Apikey xxxx-d87a-xxxx-9a36-xxxx");
      client.DefaultRequestHeaders.Add("Origin", "https://xxxxxx.com");                

    } catch(Exception e)
    {
    // has  header
    }
    HttpResponseMessage response = await client.PostAsync(processNumber.ToString(), requestData.getFormContent());
    string contents = await response.Content.ReadAsStringAsync();
    //Console.Write(response.StatusCode);
  }
}

来电帖:

private void Form1_Load(object sender, EventArgs e)
{

  var pdfFile= System.IO.File.ReadAllBytes(this.Dir + "\\" + _fileName);

  var uploadRequest = new UploadRequest(_fileName, PdfFile, "Other",
                            number,
                            DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"),
                            "99999999", "pdf");

  Upload _Upload = new Upload();
  _Upload.sendFileWs(uploadRequest, _processNumber);
}

提前谢谢了。

更新:服务器端建立在Spring Boot 2

弹簧靴 2 无过滤器:

@Override
@PostMapping("/{documentTag}/{documentId}")
public ResponseEntity<?> postFile(
    @RequestParam("file") MultipartFile file,
    @RequestParam("fileType") String fileType,
    @RequestParam("fileReference") String fileReference,
    @RequestParam("issueDate") String issueDate,
    @RequestParam("userId") String userId,
    @PathVariable(value = "documentTag") String documentTag,
    @PathVariable(value = "documentId") Long documentId) {

    logger.info("File received by File Service");

    FileInformation fileInformation = new FileInformation(FileType.of(fileType), fileReference, issueDate, userId);
    return fileUploadBusiness.upload(file, fileInformation, documentTag, documentId, request.getHeader("Authorization")
);

标签: c#postasync-await

解决方案


Form1_Load将活动的签名更改为

private async void Form1_Load(object sender, EventArgs e)

除了极少数例外,UI 事件是您应该async void在代码中看到的唯一时间。更改后,将签名更改sendFilesWs()

public async Task sendFilesWs(UploadRequest requestData, Int64 ?processNumber)

然后在你的Form1_Load事件中这样称呼它:

await _Upload.sendFileWs(uploadRequest, _processNumber);

你以前的方式:

  • 事件触发
  • 你打电话_Upload.sendFileWs()
  • 一旦代码命中,它就会将控制权返回给您的事件await client.PostAsync()
  • 事件代码继续、完成并_Upload超出范围
  • 在某些时候(确切地说,当你不能确定,因此你得到不可预知的结果),垃圾收集器清理_Upload,包括HttpClient它包含的,这将终止它打开的任何连接,因此“流意外结束”在服务器。

通过上述更改,事件现在会收到一个Task它可以等待的事件,因此_Upload现在只有在其工作完成后才会超出范围,从而防止出现问题。


推荐阅读