Ответ 1
Я получил эту работу в конце, наследуя от базового интерфейса вместо ApiController - я думаю, ApiController был modelbinding, который ждал ответ
edit: Правильная вещь для создания прокси-сервера - MessageHandler, а не ApiController
Я пишу прокси-сервер, используя WebApi в EXE файле TransferMode.Streamed HttpSelfHostConfiguration.
Когда я использую скрипт для публикации в своем ApiController, по какой-то причине я не могу прочитать Request.Content - он возвращает "", даже если у меня есть POSTed datap >
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?
Я получил эту работу в конце, наследуя от базового интерфейса вместо ApiController - я думаю, ApiController был modelbinding, который ждал ответ
edit: Правильная вещь для создания прокси-сервера - MessageHandler, а не ApiController
Я тоже боролся с этим. ReadAsStringAsync
и ReadAsAsync
вернуть объект задачи. Ссылка на свойство Result
возвращает содержимое. Он может ссылаться на свойство Result, заставляет запрос чтения async блокироваться.
Пример:
string str = response.Content.ReadAsStringAsync().Result;
Эта подпись для сообщений используется для почтовых данных:
public HttpResponseMessage Post([FromBody]string postdata)
измените его на:
public HttpResponseMessage Post()
то этот вызов отлично работает, чтобы получить данные сообщения:
string str = response.Content.ReadAsStringAsync().Result;
Протестировал это сам. используйте первую подпись, str пуста, используйте вторую строчку с данными post!
Я понимаю, что он старый, и на него ответили, но за то, что он стоит, причина, по которой вы не можете использовать 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 >
Я считаю, что вы правы в том, что 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
Я не знаю, нужна ли перемотка поиска, но я надел ее на всякий случай.
Попробуйте заменить ReadAsStringAsync()
на ReadAsAsync<string>()
.
Вы должны использовать сложный тип для своего аргумента, а затем в теле использовать некоторый json, похожий на
{путь: "c:..." }
Als используют
Content-Type: application/json; charset = UTF-8
в вашем почтовом запросе, чтобы web api знал, что json содержится в теле