【问题标题】:How to bind Json parameters to Web Api parameters in ASP.NET?如何将 Json 参数绑定到 ASP.NET 中的 Web Api 参数?
【发布时间】:2017-01-24 11:39:23
【问题描述】:

当我在 MVC 控制器中使用此方法时

[HttpPost]
public async Task<ActionResult> MyMethod(int param1, string param2)
{
   //....
}

我可以发送一个 Json 对象{param1:1, param2:"str"} 它工作得很好并且参数被解析。但是,当我为 WebApi 2 执行此操作时,它不起作用。因为根据文档中的以下示例,[FromBody] 只能由 1 个参数使用。

At most one parameter is allowed to read from the message body
    // Caution: Will not work!    
    public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

我们如何才能从 WebApi 控制器中获得与 MVC 控制器相同的行为?

编辑:创建相应的类和替换参数不是一种选择,因为消息传递工具会检查这些方法以进行维护。签名应保持不变。

【问题讨论】:

  • 您编辑提供了不可能的任务 - 最多一个参数可以从正文中读取为:“此规则的原因是请求正文可能存储在只能读取的非缓冲流中一次。”
  • @VadimLevkovsky 你是绝对正确的。但是,由于签名保持不变,我只是让该方法同时接受 GET 和 POST。当我们在 url 中发送带有参数的 GET 时,它可以工作。
  • 无法做到这一点是很痛苦的

标签: c# asp.net json asp.net-mvc asp.net-web-api


【解决方案1】:

尝试从这些值中组合一个对象:

public class Foo
{
    public int id {get;set;}
    public int name {get;set;}
}

public HttpResponseMessage Post([FromBody] Foo foo) 
{
    //some stuff...
}

如果签名应该保持不变,您可以尝试在 url 中指定参数,例如:myurl?id=1&amp;name=Tom 仍然通过 POST 动词。

【讨论】:

  • 签名应该保持不变,因为消息传递基础设施会不时检查这些控制器方法。我将使用此详细信息编辑我的问题。
【解决方案2】:

你可以这样试试:

public HttpResponseMessage Post([FromBody]dynamic value)
{
    int id= value.id.ToString();
    string name = value.name.ToString();
}

然后像下面这样传递json

{
  "id":"1",
  "name":"abc"
}

【讨论】:

  • 不要对这些事情使用动态,因为你通常知道你从前端得到什么数据。
  • 是的,但是如果你不打算创建新类来只将值传递给一个方法,并且控制器中有很多方法,那么你会怎么做?
  • 我确实创建了课程。所有请求/响应都是可能具有语义(甚至物理)价值的东西——领域对象。为什么不将它们显式公开为类?如果有很多没有意义的类 - 我会将其视为代码异味并考虑 API 重构。
【解决方案3】:

如果你必须传递多个参数,请使用类对象

public class PortalClass
{
    public ApplicationModel applicationModel { get; set; }
    public string user_id { get; set; }
    public string id { get; set; }
    public object pageCollection { get; set; }
}

public object GetApplication(PortalClass data)
{
    JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, PreserveReferencesHandling = PreserveReferencesHandling.None };
    var myObject=JsonConvert.DeserializeObject<PageCollection>(data.pageCollection.ToString(), settings)
    return null;
}

客户端:

var data = {
    user_id: userId,
    id: id
};

http.post(url, data).then(
   function (response) {

}, function (err) {
   callback.reject(err);
});

【讨论】:

  • 签名应该保持不变,因为消息传递基础设施会不时检查这些控制器方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 2013-06-18
相关资源
最近更新 更多