PostAsync适用于xml,但不适用于pdf文件

时间:2018-11-07 10:07:01

标签: c# post async-await

我无法弄清楚出了什么问题,为什么这篇文章仅对pdf文件返回Error 500,它对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

spring boot 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")
);

1 个答案:

答案 0 :(得分:0)

将您的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现在仅在其工作完成后超出范围,从而防止了该问题。