Какого типа контент при отправке файлов из браузера? - PullRequest
0 голосов
/ 03 апреля 2019

Я публикую FormData с моим внешним интерфейсом для загрузки файла (uploadReq - запрос HttpRequest)

 this.http.request(uploadReq).subscribe(event => {
      if (event.type === HttpEventType.UploadProgress)
        this.progress = Math.round(100 * event.loaded / event.total!);
      else if (event.type === HttpEventType.Response && event.body !== null)
        this.message = event.body.toString();
    });

Это затем входит в метод webapi:

   [HttpPost]
   [Route("api/uploadFiles")]
   public async Task<HttpResponseMessage> UploadFile()

Где у меня такой чек:

 if (Request.Content.IsMimeMultipartContent())

Теперь все работает нормально, если только эти 2 общаются. Однако мне нужно пропустить этот запрос через службу шлюза, и я не знаю, какой тип я должен принимать и выводить:

 [OperationContract]
 [WebInvoke(Method = "POST", UriTemplate = "uploadFiles")]
 Task<bool> uploadFiles(//what type should myFile be? Stream? StreamContent? byte[]? Something other?// myFile);

Затем мне потребуется PostAsync файл в этом методе:

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(ApiUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", someauth)));

    HttpResponseMessage response = await client.PostAsync("uploadFiles", //what should I pass here?//);
    response.EnsureSuccessStatusCode();
}

Проблема:

Мои текущие попытки сделать эту работу приводят либо к 400 bad request, либо к неудаче проверки if (Request.Content.IsMimeMultipartContent()) с 406 кодом ошибки.

Вопросы:

  1. Какой тип должен myFile быть в объявлении OperationContract?
  2. Что я должен передать в качестве параметра методу PostAsync?

РЕДАКТИРОВАТЬ: Через некоторые проб и ошибок (и много гуглить) я придумал это:

using (var client = new HttpClient())
{                           
    client.BaseAddress = new Uri(SalesQuotationApiUrl);
    client.DefaultRequestHeaders.Accept.Clear();                           
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", someAuth)));
    MultipartFormDataContent form = new MultipartFormDataContent();
    var streamContent = new StreamContent(myFile);
    var fileContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
    fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
    form.Add(fileContent, "myFile", "index.html");
    HttpResponseMessage response = await client.PostAsync("uploadFiles", form);
    response.EnsureSuccessStatusCode();
}

Это фактически отправляет файл в веб-API, и он сохраняется. Однако , это принесло мне 2 новые проблемы:

  1. Как узнать имя файла на этом этапе? form.Add(fileContent, "quoteFiles", "index.html"); <- это жестко закодировано, я хотел бы иметь оригинальное имя файла </li>
  2. Некоторый мусор добавляется к файлу - например, при отправке html-файла его начало выглядит так:

------ WebKitFormBoundaryAOjBy1u08n59PPW0 Content-Disposition: form-data; имя = "index.html"; filename = "index.html" Content-Type: Текст / HTML

Как мне убрать этот беспорядок?

1 Ответ

0 голосов
/ 04 апреля 2019

Итак, я нашел метод, который работал для меня (отправил файл, правильно обработал заголовки и оригинальные имена файлов). Может быть, кто-то может найти это полезным:

 var incomingContentType = System.ServiceModel.Web.WebOperationContext.Current.IncomingRequest.ContentType;
 var streamContent = new StreamContent(myFile);
 var incomingContentBody = streamContent.ReadAsStringAsync().Result;
 var client = new RestClient("yourApiRouteHere");
 var request = new RestRequest(Method.POST);

 request.AddHeader("cache-control", "no-cache");
 request.AddHeader("Authorization", "yourAuthHere");
 request.AddHeader("content-type", incomingContentType);
 request.AddParameter(incomingContentType, incomingContentBody, ParameterType.RequestBody);

 IRestResponse response = client.Execute(request);
 if (response.StatusCode == System.Net.HttpStatusCode.OK)
     return true;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...