2013-07-24 61 views
38

我以下形式发送请求到服务器:如何在WebAPI中获取POST数据?

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

本页面应该回答你的问题:http://www.asp.net/web-api/overview/working-with-http/sending-html- form-data,-part-1 –

+1

@JonnyS它做到了。这是一个耻辱,虽然,你反过来,因为否则我可以接受你的答案:) – Spook

+1

http://stackoverflow.com/questions/13120971/how-to-get-post-values-with -asp-net-webapi – drzaus

回答

53

answer在这样一个问题: How to get Json Post Values with asp.net webapi

  1. 使用参数绑定

    Autoparse;请注意0​​由JToken组成,因此.Value访问者。

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

    public async Task Post() {   
        dynamic obj = await Request.Content.ReadAsAsync<JObject>(); 
        var y = obj.var1; 
    } 
    
  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... 
    } 
    

使用警告 - 预计媒体类型application/json为了触发JsonMediaTypeFormatter处理。

+0

你也可以使用return p.Result [key ]。值(); –

+0

@ManuelKoch谢谢。我想他们在过去的4年里增加了便利;) – drzaus

8

我在使用多个参数发送请求时遇到了问题。

我已经通过发送一个类,使用旧的参数作为属性来解决它。

<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; 
} 
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

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); 
     } 
13

今天花的时间定好位之后试图将我的大脑围绕处理Web表单数据的旧方式以及WebAPI如何完成之间的(重要但强大的)范式转换进行,我想我会将2美分添加到此讨论中。

我想做什么(这对POST的Web表单处理非常常见)就是能够以任意顺序获取我想要的任何表单值。如果你有你的数据在System.Collections.Specialized.NameValueCollection,就像你可以做的一样。但事实证明,在WebAPI中,来自POST的数据以流的形式返回给您。所以你不能直接做到这一点。

但是有一个很酷的小类FormDataCollection(在System.Net.Http.Formatting中),它可以让你做的是迭代你的集合一次。

所以我写了一个简单的实用程序方法,它将运行一次FormDataCollection并将所有值保存到NameValueCollection中。完成此操作后,您可以将所有数据跳到您的内容。

所以在我ApiController派生类中,我有一个帖子方法是这样的:在我的静态WebAPIUtils类

public void Post(FormDataCollection formData) 
    { 
     NameValueCollection valueMap = WebAPIUtils.Convert(formData); 

     ... my code that uses the data in the NameValueCollection 
    } 

转换方法是这样的:

/// <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

您只需复制其他用户的其他答案:Brandon Bearden –

+0

这个变体是'public void Post(Dictionary formData)''这也是可行的 – testpattern

+0

@LeandroTupone这是_not_副本布兰登比尔登的答案:http://stackoverflow.com/a/23943276/555798然而,布拉德的基础上他的答案斯科特斯通的(没有提及他的链接或链接到重复的问题):http://stackoverflow.com/a/26393562/555798虽然我很高兴的答案,因为它在这里,我发现我需要使用FormDataCollection'为我的WebHook与另一个供应商合作。 – MikeTeeVee

0

试试这个。

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

    // ... 
} 

它为我的WebAPI 2