Переслать запрос ASP.Net WebAPI к другому API - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь переслать запрос от одного API к другому, как это:

protected Task<HttpResponseMessage> ForwardRequestToSomeApi()
{
    string forwardUri = "https://some.api" + Request.RequestUri.PathAndQuery;

    Request.Headers.Remove("Host");
    Request.RequestUri = new Uri(forwardUri);
    if (Request.Method == HttpMethod.Get)
    {
        Request.Content = null;
    }

    return new HttpClient().SendAsync(Request, HttpCompletionOption.ResponseHeadersRead);
}

но при отправке запроса PUT я получаю:

Невозможно закрыть поток, пока не будут записаны все байты.

Полная информация об исключении:

{"Message":"An error has occurred.","ExceptionMessage":"An error occurred while sending the request.","ExceptionType":"System.Net.Http.HttpRequestException","StackTrace":"
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__1`1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n
   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"The request was aborted: The request was canceled.","ExceptionType":"System.Net.WebException","StackTrace":"
   at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)\r\n
   at System.Net.ConnectStream.System.Net.ICloseEx.CloseEx(CloseExState closeState)\r\n
   at System.Net.ConnectStream.Dispose(Boolean disposing)\r\n
   at System.IO.Stream.Close()\r\n
   at System.Net.Http.HttpClientHandler.<>c__DisplayClass109_0.<GetRequestStreamCallback>b__0(Task task)","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Cannot close stream until all bytes are written.","ExceptionType":"System.IO.IOException","StackTrace":"
   at System.Net.ConnectStream.CloseInternal(Boolean internalCall, Boolean aborting)"}}}

Внутреннее исключение:

Сообщение IOException: «Невозможно закрыть поток, пока все байты не будут написано. "StackTrace: в System.Net.ConnectStream.CloseInternal (логический internalCall, логический прерывание)

Обновление:

Если приведенный выше код полностью работает, проблема заключалась в том, как я пытался его использовать. В моем основном API у меня было следующее действие webapi:

[HttpPut]
public Task<HttpResponseMessage> Create(string id, Foo model)
{
   return ForwardRequestToSomeApi();
}

Проблема здесь в том, что я ввел модель в параметры, благодаря тому, что содержимое запроса привязки модели было прочитано и проанализировано в модели, поэтому, когда я пересылаю запрос в другой API, я отправляю запрос без содержимого. Исправлено удаление всех параметров:

[HttpPut]
public Task<HttpResponseMessage> Create()
{
   return ForwardRequestToSomeApi();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...