如何在WebAPI中获取POST数据?

Spo*_*ook 49 asp.net asp.net-web-api

我正在以下列形式向服务器发送请求:

http://localhost:12345/api/controller/par1/par2
Run Code Online (Sandbox Code Playgroud)

请求已正确解析为以下方法:

[HttpPost]
public void object Post(string par1, string par2)
Run Code Online (Sandbox Code Playgroud)

但是,我通过请求内容传递了其他数据.我该如何检索这些数据?

为了举例,我们说,请求是从表单发送的:

<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>
Run Code Online (Sandbox Code Playgroud)

drz*_*aus 66

从这个问题的答案: 如何使用asp.net webapi获得Json Post值

  1. 使用参数绑定自动进行; 注意,dynamic是由JToken,因此.Value访问.

    public void Post([FromBody]dynamic value) {
        var x = value.var1.Value; // JToken
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 阅读就像 Request.RequestUri.ParseQueryString()[key]

    public async Task Post() {        
       dynamic obj = await Request.Content.ReadAsAsync<JObject>();
       var y = obj.var1;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 与#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...
    }
    
    Run Code Online (Sandbox Code Playgroud)

警告 - 期望媒体类型application/json以触​​发JsonMediaTypeFormatter处理.


小智 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
    }
Run Code Online (Sandbox Code Playgroud)

我的静态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;
     }
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!


Cor*_*ert 12

发送带有多个参数的请求时遇到问题.

我通过发送一个类来解决它,将旧参数作为属性.

<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>
Run Code Online (Sandbox Code Playgroud)

型号类:

public class Model {
    public string Name1 { get; set; }
    public string Name2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

public void method(Model m) {
    string name = m.Name1;
}
Run Code Online (Sandbox Code Playgroud)


Cur*_*lop 9

很难直接处理动作上的多个参数.更好的方法是创建一个视图模型类.然后您有一个参数,但该参数包含多个数据属性.

public class MyParameters
{
    public string a { get; set; } 
    public string b { get; set; }
}

public MyController : ApiController
{
    public HttpResponseMessage Get([FromUri] MyParameters parameters) { ... }
}
Run Code Online (Sandbox Code Playgroud)

然后你去:

http://localhost:12345/api/MyController?a=par1&b=par2
Run Code Online (Sandbox Code Playgroud)

参考: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


小智 6

尝试这个。

public string Post(FormDataCollection form) {
    string par1 = form.Get("par1");

    // ...
}
Run Code Online (Sandbox Code Playgroud)

它适用于我的 webapi 2