【问题标题】:Can you use a named JSON property to pass a complex object to a C# controller?您可以使用命名 JSON 属性将复杂对象传递给 C# 控制器吗?
【发布时间】:2018-08-22 01:42:59
【问题描述】:

当我尝试在我的 JSON 对象中分配一个属性名称时,我遇到了一些 JSON 数据在我的 Web API 控制器上的 POST 方法的参数中填充 C# 对象的问题。

这是我的 API 控制器:

[HttpPost]
public HttpResponseMessage MyResource(MyComplexClass myClass)
{
    var test = myClass.Name;

    return Request.CreateResponse(HttpStatusCode.Created);
}

这里是MyComplexClass

public class MyComplexClass
{
    public string Name { get; set; }
    public string Id { get; set; }
}

这是我的AJAX 电话:

<script>
    function test() {
        var innerData = {
            Name: 'Bob Loblaw',
            Id: "1"
        };

        var myData = {
            myClass: innerData
        };

        $.ajax({
            type: "POST",
            url: "api/Test/MyResource",
            data: JSON.stringify(myData),
            contentType: "application/json",
            dataType: "json",
            success: function (response) {
                // do success stuff
            },
            error: function (err) {
                // do error stuff
            }
        });
    }
</script>

问题是:当我在我的JS代码中将innerData对象作为属性包含在myData对象中时,myClass对象的属性都是null

我知道如果我将innerData 传递给AJAX 调用本身,myClass 对象会被正确填充,但我很好奇为什么我不能使用命名的 JSON 属性来传递复杂的C# 对象到控制器。

有谁知道如何将myClass 对象作为命名的 JSON 属性传递,或者你能解释一下为什么我不能?

改写的问题:

如果这个 JSON 对象:

var data = {
    Name: 'Bob Loblaw',
    Id: "1"
};

匹配这个控制器方法:

public HttpResponseMessage MyResource(string Name, string Id)

为什么没有这个 JSON 对象:

var data = {
    myClass: { Name: 'Bob Loblaw', Id: "1" }
};

匹配这个控制器方法吗?

public HttpResponseMessage MyResource(MyComplexClass myClass)

其他问题:

是否可以将 API 方法声明如下:

public HttpResponseMessage MyResource(MyComplexClass myClass, string anotherValue)

如果是这样,JSON 对象将如何构造?

【问题讨论】:

  • 试试var myData = innerData;然后发送
  • MyComplexClass 期待一个有两个键的对象;姓名和身份证。但你没有给它。所以它没有任何东西可以映射到。 MyComplexClass 没有 myClass 字段可以正确地将您的输入映射到它
  • 是 Web API 2 吗?
  • 不,我正在使用 MVC 版本 5.2.3 和类似版本的 Web API

标签: c# jquery ajax asp.net-mvc api


【解决方案1】:

为什么没有这个 JSON 对象:

var data = {
    myClass: { Name: 'Bob Loblaw', Id: "1" }
};

匹配这个控制器方法吗?

public HttpResponseMessage MyResource(MyComplexClass myClass)

由于模型绑定在 WEB API 中的工作方式,当您发送时

var data = {
    Name: 'Bob Loblaw',
    Id: "1"
};

WEB API将你发送的json对象的属性绑定到你定义为参数的类的属性上。

所以,为了匹配

var data = {
    myClass: { Name: 'Bob Loblaw', Id: "1" }
};

MyComplexClass 需要定义为

public class MyComplexClass
{
    public Object myClass{ get; set; }
}

【讨论】:

  • 所以更进一步:我可以看到这样的 Web API 方法声明:public HttpResponseMessage MyResource(MyComplexClass myClass, string anotherValue),如果可以,该 JSON 对象将如何构造?感谢您的帮助!
  • 人们倾向于做的是,而不是拥有多个参数(MyComplexClass myClass, string anotherValue),而是定义一个模型(类)来组合您需要的所有属性。因此,如果 MyComplexClass 有 2 个属性,您只需为具有这 2 个属性和一个字符串的资源创建一个新类。在 MVC 中它们被称为视图模型,查看它们
  • 但是,如果你坚持 json 是 var data = { Name: 'Bob Loblaw', Id: "1" , anotherValue : "Johnny"} 就可以了
  • 好的,谢谢!我有点想多参数的东西是一个糟糕的标准。我问的原因是我正在编写一个自我记录的 API 工具,它允许用户尝试一种方法(基本上是自动化 Postman 表单),并试图预测任何可能导致麻烦的糟糕 API 设计。
  • docs.microsoft.com/en-us/aspnet/web-api/overview/…。 ApiControllers 的行为与 MVC 中使用的控制器不同,为简单起见,它们不直接将多个对象作为参数工作,如果要使用多个对象,则必须创建模型绑定器,或者创建一个包含所有对象的统一模型您需要的属性
【解决方案2】:

这是因为您已经嵌套了 innerData 对象,而 C# 不知道它是什么。您可以不通过将 innerData 传递给 ajax 来嵌套该对象,也可以像这样为您的 C# 对象添加另一层:

public class MyOuterClass
{
    public MyComplexClass innerData { get; set; }
}

【讨论】:

  • 我不明白的是,这个方法声明:public HttpResponseMessage MyResource(MyComplexClass myClass) 和这个:public HttpResponseMessage MyResource(string Name, string Id) 在处理 JSON 对象时的处理方式相同。 MVC 框架中有什么东西决定了这一点吗?
  • 我在问题帖子的底部添加了一些额外的措辞,可能会澄清我在问什么
  • 我认为这里缺少的可能是json对象的序列化?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
  • 2017-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多