Как получить данные POST в WebAPI?
Я отправляю запрос на сервер в следующей форме:
http://localhost:12345/api/controller/par1/par2
Запрос правильно разрешен к методу, например:
[HttpPost]
public void object Post(string par1, string par2)
Однако я передаю дополнительные данные через содержимое запроса. Как я могу получить эти данные?
Например, скажем, что запрос отправляется из формы:
<form action="http://localhost:12345/api/controller/par1/par2" method="post">
<input type="hidden" name="data" value="value" />
<input type="submit" name="submit" value="Submit" />
</form>
Ответы
Ответ 1
От ответ в этом вопросе:
Как получить значения Json Post с помощью asp.net webapi
-
Автопарк с использованием привязки параметров; обратите внимание, что dynamic
состоит из JToken
, следовательно, аксессуар .Value
.
public void Post([FromBody]dynamic value) {
var x = value.var1.Value; // JToken
}
-
Прочитайте так же, как Request.RequestUri.ParseQueryString()[key]
public async Task Post() {
dynamic obj = await Request.Content.ReadAsAsync<JObject>();
var y = obj.var1;
}
-
То же, что и # 2, просто не асинхронно (?), поэтому вы можете использовать его в вспомогательном методе
private T GetPostParam<T>(string key) {
var p = Request.Content.ReadAsAsync<JObject>();
return (T)Convert.ChangeType(p.Result[key], typeof(T)); // example conversion, could be null...
}
Caveat - ожидает медиа-тип application/json
для запуска обработки JsonMediaTypeFormatter
.
Ответ 2
Сегодня, проведя немало времени, пытаясь обернуть мой мозг вокруг (значительного, но мощного) смещения парадигмы между старыми способами обработки данных веб-формы и тем, как это делается с помощью WebAPI, я думал, что добавлю свои 2 цента к этому обсуждению.
То, что я хотел сделать (что довольно часто используется для обработки веб-форм POST), состоит в том, чтобы иметь возможность захватывать любые значения форм, которые я хочу, в любом порядке. Скажите, что вы можете сделать, если у вас есть данные в System.Collections.Specialized.NameValueCollection
. Но получается, что в WebAPI данные из POST возвращаются к вам в качестве потока. Поэтому вы не можете напрямую это сделать.
Но есть класс классного маленького класса с именем FormDataCollection
(в System.Net.Http.Formatting), и то, что он позволит вам сделать, - это перебирать вашу коллекцию один раз.
Итак, я написал простой метод утилиты, который будет запускаться через FormDataCollection
один раз и вставить все значения в NameValueCollection
. Как только это будет сделано, вы можете перескакивать по всем данным в ваш контент.
Итак, в моем производном классе ApiController у меня есть метод post, подобный этому:
public void Post(FormDataCollection formData)
{
NameValueCollection valueMap = WebAPIUtils.Convert(formData);
... my code that uses the data in the NameValueCollection
}
Метод Convert в моем статическом классе WebAPIUtils выглядит следующим образом:
/// <summary>
/// Copy the values contained in the given FormDataCollection into
/// a NameValueCollection instance.
/// </summary>
/// <param name="formDataCollection">The FormDataCollection instance. (required, but can be empty)</param>
/// <returns>The NameValueCollection. Never returned null, but may be empty.</returns>
public static NameValueCollection Convert(FormDataCollection formDataCollection)
{
Validate.IsNotNull("formDataCollection", formDataCollection);
IEnumerator<KeyValuePair<string, string>> pairs = formDataCollection.GetEnumerator();
NameValueCollection collection = new NameValueCollection();
while (pairs.MoveNext())
{
KeyValuePair<string, string> pair = pairs.Current;
collection.Add(pair.Key, pair.Value);
}
return collection;
}
Надеюсь, это поможет!
Ответ 3
Трудно обрабатывать сразу несколько параметров. Лучший способ сделать это - создать класс модели представления. Затем у вас есть один параметр, но параметр содержит несколько свойств данных.
public class MyParameters
{
public string a { get; set; }
public string b { get; set; }
}
public MyController : ApiController
{
public HttpResponseMessage Get([FromUri] MyParameters parameters) { ... }
}
Затем вы переходите к:
http://localhost:12345/api/MyController?a=par1&b=par2
Ссылка: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
Если вы хотите использовать "/par1/par2", вы можете зарегистрировать правило маршрутизации asp. например routeTemplate: "API/{controller}/{action}/{a}/{b}".
См. http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
Ответ 4
У меня возникла проблема с отправкой запроса с несколькими параметрами.
Я решил его, отправив класс со старыми параметрами в качестве свойств.
<form action="http://localhost:12345/api/controller/method" method="post">
<input type="hidden" name="name1" value="value1" />
<input type="hidden" name="name2" value="value2" />
<input type="submit" name="submit" value="Submit" />
</form>
Модельный класс:
public class Model {
public string Name1 { get; set; }
public string Name2 { get; set; }
}
Контроллер:
public void method(Model m) {
string name = m.Name1;
}
Ответ 5
Я нашел для моего использования случай, это было намного более полезно, надеюсь, это помогает кому-то еще, что потратил время на этот ответ, применяя его
public IDictionary<string, object> GetBodyPropsList()
{
var contentType = Request.Content.Headers.ContentType.MediaType;
var requestParams = Request.Content.ReadAsStringAsync().Result;
if (contentType == "application/json")
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<IDictionary<string, object>>(requestParams);
}
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
Ответ 6
Есть ли способ обработать данные формы сообщения в контроллере Web Api?
Обычный подход в ASP.NET Web API заключается в представлении формы в качестве модели, поэтому форматор медиа-типа десериализует его. Альтернативой является определение параметра actions как NameValueCollection:
public void Post(NameValueCollection formData)
{
var value = formData["key"];
}
Ответ 7
Попробуйте это.
public string Post(FormDataCollection form) {
string par1 = form.Get("par1");
// ...
}
Он работает для меня с webapi 2