如何在 Web API 控制器 Post 方法中接收动态数据

How to receive dynamic data in Web API controller Post method

jqgrid 在 POST 请求缓冲区中发布 json 数据作为

{"headerData": {
    "Tasudok": "134",
    "Kuupaev": "2015-11-23",
    "Dokumnr": "135319"
   },


"rowData": {
  "Toode":"",
  "Kogus":"0.0000",
  "Nimetus":"öäölä<a",
  "_rowsum":"0.00",
  "Id":"1639",
  "Dokumnr":"135319",
  "_oper":"edit",
  "_rowid":"1639"
  }
}

数据发布到 ASP.NET MVC4 Web API 使用 URL 就像 API/Entity/someid?culture=en&layout=1 和默认路由。

headerDatarowData 值属性在运行时定义并且可以变化。

例如,在某些调用中,rowData 可能包含其他属性,而某些 rowData 属性可能会丢失。

culturelayout 查询字符串参数是可选的。

如何在WebAPI控制器中接收参数?

我试过了

public class EntityController : APIController
{

public class PostParams {
    public string culture { get; set; }
    public int? layout { get; set; }
    }

    public HttpResponseMessage Post(string id, 
      [FromUri]PostParams optionalParams,
      [FromBody]IList<NameValue> headerData,
      [FromBody]IList<NameValue> rowData )
    { ... }


public class NameValue
{
    public string name, value;
}
}

但是 headerData 和 rowData 是空的。如何获取所有参数?

如果JSON的结构不变

有了这个,您就可以像在 url 中提供的那样发送 body API/Entity/someid?culture=en&layout=1.

要在你的控制器路由中指定可选的查询参数,给它们一个默认值,比如:

public class EntityController : APIController
{
    public HttpResponseMessage Post([FromUri]string culture="EN", [FromUri]int layout=1, YourBody body )
    { ... }
}

如果 YourBody 总是像您提到的那样,那么应该自动反序列化这样的东西:

public class YourBody
{
    public Dictionary<string, string> HeaderData {get; set;}
    public Dictionary<string, string> RowData{get; set;}
}

并且可以让您完全访问 body.

的任何元素

如果JSON的结构可以改变

像这样的东西将允许接收任何类型的 json:

public HttpResponseMessage  Post([FromBody]JToken body)
{
    // Process the body
    return ...
}

您将需要一些额外的验证,因为不会进行 object 反序列化。您唯一知道的是您的 body 是 JSON.

因此,您可能需要对其进行解析,看看它是否与您期望的一样。 参见 that post about how to access element of a JSON with JToken

例如,您可以执行类似以下的操作来处理不断变化的 body 内容,并且仍然处理路由的可选查询参数:

public HttpResponseMessagePost([FromBody]JToken body, [FromUri]string culture="EN", [FromUri]int layout=1)
{
    JObject headerData= body["headerData"].Value<JObject>();
    JObject headerData= body["rowData"].Value<JObject>();
    return ...;
}

您还可以阅读 this 关于将原始数据发布到 webapi 控制器的其他替代方法。