【问题标题】:Posting JSON Data containing an array to Controller Action将包含数组的 JSON 数据发布到控制器操作
【发布时间】:2012-04-02 01:11:55
【问题描述】:

在 ASP.NET MVC3 应用程序中,我正在尝试使用 jQuery 对操作进行异步发布。

以下 JSON 对象正在作为数据传递...

{
    categoryId: "21"
    content: "asdf"
    reference: "asdf"
    tags: [
        {id: 1, name: "asdf", status: 1},
        {id: 2, name: "asdf", status: 1},
        {id: 3, name: "asdf", status: 1}
    ]
}

我必须接收请求的方法签名是

[HttpPost]
public ActionResult Create(String reference, Int32? categoryId, String content, IEnumerable<TagDTO> tags)

使用 TagDTO 被定义为:

public class TagDTO
{
    public String name { get; set; }
    public Int32 id { get; set; }
    public Int32 status { get; set; }
}

我应该提到,在我将对象数组引入 JSON 对象和操作方法的签名之前,这是完美的。并且 Post 仍然成功地到达了 action,只是 IEnumerable 中的数据没有正确通过。它会给我正确数量的 IEnumerable 中的对象,但它们都被初始化为默认值。 (id=0, name=null, status=0)

我不确定我在这里做错了什么。我希望这是有道理的。我希望有人可以向我展示以这种方式将数据传递给 MVC 操作的正确方法。

谢谢


这是我用来执行 ajax 调用的 javascript 函数...

function saveResource() {
    var tagAssignments = [];
    for (var x = 0; x < $('.tag-assignment').length; x++) {
        var tag = $($('.tag-assignment')[x]);
        tagAssignments.push({
            name: tag.find('.tag-name').html().toString(),
            id: parseInt(tag.find('.tag-id').html()),
            status: parseInt(tag.find('.tag-status').html())
        });
    }

    $.ajax({
        url: '/Resources/Create',
        dataType: 'json',
        type: 'POST',
        success: function (data) {
            if (data.status == 'Success') {
                forwardToDefaultPage();
            } else {
                alert(data.status);
            }
        },
        data: {
            reference: $('#txt-resource-reference').val(),
            categoryId: $('#ddl-category').val(),
            content: $('#txt-resource-content').val(),
            tags: tagAssignments
        }
    });
}

【问题讨论】:

  • 请贴出你的ajax调用代码
  • 我会尝试将所有输入参数放入一个对象中,包括数组
  • 您的视图中的 name 属性是否完全合格,即 tags[0].name 和 tags[1].name 等 也许发布您的视图代码也可能有所帮助

标签: c# json asp.net-mvc-3 jquery


【解决方案1】:

我会建议您使用视图模型并发送 JSON 请求。

所以一个视图模型:

public class CreateViewModel
{
    public string Reference { get; set; }
    public int? CategoryId { get; set; }
    public string Content { get; set; }
    public IEnumerable<TagDTO> Tags { get; set; }
}

行动:

[HttpPost]
public ActionResult Create(CreateViewModel model)
{
    ...
}

AJAX 请求:

// TODO: build this object dynamically as you are currently doing
// but always start with hardcoded values like this to test first
var data = {
    categoryId: '21',
    content: 'asdf',
    reference: 'asdf',
    tags: [
        { id: 1, name: 'asdf', status: 1 },
        { id: 2, name: 'asdf', status: 1 },
        { id: 3, name: 'asdf', status: 1 }
    ]
};

$.ajax({
    url: '@Url.Action("create", "resources")',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({ model: data }),
    success: function(result) {
        ...
    }
});

这里使用的JSON.stringify 方法内置于现代浏览器中。如果您需要支持旧版浏览器,可以将json2.js 脚本添加到您的页面。

【讨论】:

  • 只是一个语义问题......如果模型被用于通过 AJAX 请求来回传输数据并且只处理视图中包含的部分内容,那么它应该被称为 ViewModel 吗?还是应该只叫模型?
  • @jdavis,控制器动作总是将视图模型作为参数,并且总是将视图模型传递给视图。
【解决方案2】:

有几件事可以尝试。

看看改变你的ajax调用,如下所示。

function saveResource() {

   var tagAssignments = [];
   for (var x = 0; x < $('.tag-assignment').length; x++) {
       var tag = $($('.tag-assignment')[x]);
       tagAssignments.push({
           name: tag.find('.tag-name').html().toString(),
           id: parseInt(tag.find('.tag-id').html()),
           status: parseInt(tag.find('.tag-status').html())
       });
   }

   $.ajax({
       url: '<%: Url.Action("Create", "Resources")',
       dataType: 'json',
       type: 'POST',
       success: function (data) {
           if (data.status == 'Success') {
               forwardToDefaultPage();
           } else {
               alert(data.status);
           }
       },
       data: {
           reference: $('#txt-resource-reference').val(),
           categoryId: $('#ddl-category').val(),
           content: $('#txt-resource-content').val(),
           tags: JSON.stringify(connect)        
       }
   });

}

并在您的操作中将您的 IEnumerable 更改为 IList

   [HttpPost]
   public ActionResult Create(String reference, Int32? categoryId, String content, IEnumerable<TagDTO> tags)

【讨论】:

    猜你喜欢
    • 2012-04-17
    • 2015-08-02
    • 2012-11-26
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多