Подтвердить что ты не робот

Не удается прочитать Request.Content в контроллере ASP.NET WebApi

Я пишу прокси-сервер, используя WebApi в EXE файле TransferMode.Streamed HttpSelfHostConfiguration.

Когда я использую скрипт для публикации в своем ApiController, по какой-то причине я не могу прочитать Request.Content - он возвращает "", даже если у меня есть POSTed data​​p >

public class ApiProxyController : ApiController
{

    public Task<HttpResponseMessage> Post(string path)
    {
        return Request.Content.ReadAsStringAsync().ContinueWith(s =>
        {
            var content = new StringContent(s.Result); //s.Result is ""
                CopyHeaders(Request.Content.Headers, content.Headers);
            return Proxy(path, content);
        }).Unwrap();
    }

    private Task<HttpResponseMessage> Proxy(string path, HttpContent content)
    {
        ...
    }
}

Вот мой веб-запрос

POST http://localhost:3001/api/values HTTP/1.1
Host: localhost:3001
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Content-Type: application/json
Content-Length: 26

{ "text":"dfsadfsadfsadf"}

Что я делаю неправильно? Почему s.Result возвращается как пустая строка, а не сырой json?

4b9b3361

Ответ 1

Я получил эту работу в конце, наследуя от базового интерфейса вместо ApiController - я думаю, ApiController был modelbinding, который ждал ответ

edit: Правильная вещь для создания прокси-сервера - MessageHandler, а не ApiController

Ответ 2

Я тоже боролся с этим. ReadAsStringAsync и ReadAsAsync вернуть объект задачи. Ссылка на свойство Result возвращает содержимое. Он может ссылаться на свойство Result, заставляет запрос чтения async блокироваться.

Пример:

string str = response.Content.ReadAsStringAsync().Result;

Ответ 3

Эта подпись для сообщений используется для почтовых данных:

public HttpResponseMessage Post([FromBody]string postdata)

измените его на:

public HttpResponseMessage Post()

то этот вызов отлично работает, чтобы получить данные сообщения:

string str = response.Content.ReadAsStringAsync().Result;

Протестировал это сам. используйте первую подпись, str пуста, используйте вторую строчку с данными post!

Ответ 4

Я понимаю, что он старый, и на него ответили, но за то, что он стоит, причина, по которой вы не можете использовать ReadAsStringAsync(), не потому, что она "ест данные", как было предложено, потому что контент обрабатывается как поток, и поскольку данные были использованы форматором сообщений, положение потока уже находится в конце.

Чтобы использовать ReadAsStringAsync(), вам сначала нужно reset положение потока контента в начало.

Я делаю это так: response.RequestMessage.Content.ReadAsStreamAsync().Result.Seek( 0, System.IO.SeekOrigin.Begin ), потому что у меня только HttpResponseMessage, но если у вас есть прямой доступ к HttpRequestMessage (как и внутри контроллера), вы можете использовать Request.Content.ReadAsStreamAsync().Result.Seek( 0, System.IO.SeekOrigin.Begin ), который функционально эквивалентен./p >

Ответ 5

Я считаю, что вы правы в том, что ApiController питается Request.Content. Объект "Запрос", который вы видите в ApiController, фактически имеет тип System.Net.Http.HttpRequestMessage. Мне удалось обойти эту проблему, но резервное копирование на объект System.Web.HttpRequest, например:

Dim content as string
If HttpContext.Current.Request.InputStream.CanSeek Then
    HttpContext.Current.Request.InputStream.Seek(0, IO.SeekOrigin.Begin)
End If
Using reader As New System.IO.StreamReader(HttpContext.Current.Request.InputStream)
    content = reader.ReadToEnd()
End Using

Я не знаю, нужна ли перемотка поиска, но я надел ее на всякий случай.

Ответ 6

Попробуйте заменить ReadAsStringAsync() на ReadAsAsync<string>().

Ответ 7

Вы должны использовать сложный тип для своего аргумента, а затем в теле использовать некоторый json, похожий на

{путь: "c:..." }

Als используют

Content-Type: application/json; charset = UTF-8

в вашем почтовом запросе, чтобы web api знал, что json содержится в теле

Ответ 8

  • Request.Content.ReadAsStreamAsync(). Result.Seek(0, System.IO.SeekOrigin.Begin)
  • новый System.IO.StreamReader(Request.Content.ReadAsStreamAsync(). Результат).ReadToEnd()