无法将List <model>从AngularJS传递到.NET MVC

时间:2017-08-09 20:52:05

标签: c# angularjs json asp.net-mvc

我知道这个问题在SO上被问了一百次,但没有一个解决方案对我有帮助。我尝试做一些应该简单的事情:将一个对象列表从我的AngularJS(又名Angular 1)前端传递给.NET MVC控制器端点。

以下是相关JavaScript的简化版本:

var data = [{ A: 1, B: 2 }, { A: 3, B: 4 }];
$http.post(baseUrl + 'ap/underwriting', data);

这里是.NET控制器端点:

[AcceptVerbs(HttpVerbs.Post)]
public async Task<string> Underwriting(List<MyViewModel> list)
{
    return await DoSomethingWith(list);
}

当我尝试POST到此端点时,我无法到达断点,因此在操作中的代码运行之前它会失败。奇怪的是,我得到200回复​​作为回应状态,尽管这可能是我工作环境的一件神器。

我可以确认JavaScript对象与MyViewModel匹配(实际上,它们实际上是由返回List的GET调用创建的)。我还可以确认端点是否正确连接,因为我尝试使用不包含List的模型进行连接并且它可以工作,并按预期绑定数据。

我尝试将List设为父模型的属性,然后传递父模型,如下所示:

JS:

var data = { Name: 'Whatever', 'Steps': [{ A: 1, B: 2 }, { A: 3, B: 4 }] };
$http.post(baseUrl + 'ap/underwriting', data);

C#型号:

public class MyParentModel
{
    public string Name { get; set; }
    public List<MyViewModel> Steps { get; set; }
}

控制器操作:

[AcceptVerbs(HttpVerbs.Post)]
public async Task<string> Underwriting(MyParentModel model)
{
    return await DoSomethingWith(model.Steps);
}

这以同样的方式失败。但是,如果我在MyParentModel类中注释掉Steps属性,则端点可以正常工作,并且Name属性可以正确显示。因此,我非常有信心问题在于.NET试图绑定List。

在JS方面,我尝试使用JSON.stringify手动序列化数据。我也尝试过明确地将它变成JSON对象:

var data = { list: [{ A: 1, B: 2 }, { A: 3, B: 4 }] };
$http.post(baseUrl + 'ap/underwriting', data);

我还确保POST的Content-Type是application / json(AngularJS会自动执行此操作)。

在.NET方面,我尝试将参数类型设为IList和MyViewModel []。

我觉得这应该很简单,但我知道.NET有问题。我错过了什么?

谢谢!

3 个答案:

答案 0 :(得分:1)

好吧,我明白了。我没有看到在这个常见问题的其他地方提到的这个原因,所以我自我回答把它放在那里。

我遇到的问题是我为MyViewModel类编写了一个具有特定参数的构造函数方法。因此,.NET与List无关,而是它无法创建MyViewModel类的成员,因为它无法调用构造函数。解决方案是添加第二个没有参数的构造函数。

答案 1 :(得分:0)

我不是Angular专家,而是以MVC视图为例。如果您要执行标准帖子,则扩展方法会生成以下元素:

<input type="text" name="Steps[0].A" />

匹配您的模型,因此序列化的FORM POST将使用以下语法:

Steps[0].A=1&Steps[0].B=2

用于后期操作。你的例子:

var data = { Name: 'Whatever', 'Steps': [{ A: 1, B: 2 }, { A: 3, B: 4 }] }

最接近,但从其他一些例子看,通过jQuery,似乎你必须序列化数组(使用jQuery的一些例子):

编辑:虽然这个解决方案似乎适用于其他人:

答案 2 :(得分:0)

将[FromBody]添加到api方法中,看起来就是这样;

然后模型转换器应该将您的简单数据转换为匹配的viewmodel。

[AcceptVerbs(HttpVerbs.Post)]
public async Task<string> Underwriting([FromBody] List<MyViewModel> list)
{
    return await DoSomethingWith(list);
}

HTH 史蒂夫