我正在以下列形式向服务器发送请求:
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>
答案 0 :(得分:64)
在这个问题中来自answer: How to get Json Post Values with 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...
}
警告 - 期望媒体类型application/json
以便触发JsonMediaTypeFormatter
处理。
答案 1 :(得分:20)
今天花了很多时间试图围绕处理Web表单数据的旧方式与WebAPI处理之间的(重要但强大的)范式转换,我想我会加上我的2美分讨论。
我想要做的事情(对于POST的Web表单处理来说很常见)是能够以任何顺序获取我想要的任何表单值。如果您的数据位于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
}
我的静态WebAPIUtils类中的Convert方法如下所示:
/// <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;
}
希望这有帮助!
答案 2 :(得分:10)
发送带有多个参数的请求时出现问题。
我通过发送一个类来解决它,将旧参数作为属性。
<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;
}
答案 3 :(得分:9)
直接处理动作的多个参数很困难。更好的方法是创建一个视图模型类。然后你有一个参数,但参数包含多个数据属性。
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 :(得分:3)
我发现我的用例更有用,希望它可以帮助其他人花时间在这个答案上应用它
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);
}
答案 5 :(得分:2)
Is there a way to handle form post data in a Web Api controller?
ASP.NET Web API中的常规方法是将表单表示为模型,以便媒体类型格式化程序对其进行反序列化。另一种方法是将动作的参数定义为NameValueCollection:
public void Post(NameValueCollection formData)
{
var value = formData["key"];
}
答案 6 :(得分:2)
这里没有答案对我有用。在post方法中使用FormDataCollection似乎是正确的答案,但是关于我的post请求的某些原因导致webapi阻塞。最终,我通过在方法调用中不包含任何参数,而只是手动解析出这样的表单参数来使它起作用。
{{1}}
答案 7 :(得分:1)
试试这个。
public string Post(FormDataCollection form) {
string par1 = form.Get("par1");
// ...
}
它适用于webapi 2