【问题标题】:What is the correct model for binding this complex nested json绑定这个复杂的嵌套 json 的正确模型是什么
【发布时间】:2011-12-07 12:29:35
【问题描述】:

我整天都在尝试在 asp.net mvc3 中构建一个模型来处理这个 json 帖子。我查看了大多数 stackoverflow'post 但仍然无法成功构建它。 json数据如下

{"form":[{
          "ora1":{"start":"08:00:00","end":"08:50:00"},
          "ora2":{"start":"09:00:00","end":"09:50:00"},
          "ora3":{"start":"10:00:00","end":"10:50:00"},            
          "...":{"start":"12:10:00","end":"13:00:00"},
          "oran":{"start":"12:10:00","end":"13:00:00"}
         }]}

甚至

 {"form":
    {"Monday":
          {
             "ora1":{"start":"08:00:00","end":"08:50:00"},
             "ora2":{"start":"09:00:00","end":"09:50:00"},
             "ora3":{"start":"10:00:00","end":"10:50:00"},
             "....":{"start":"11:10:00","end":"12:00:00"},
             "oran":{"start":"12:10:00","end":"13:00:00"}
            }
     },
     {"Tuesday":
          {
             "ora1":{"start":"08:00:00","end":"08:50:00"},
             "ora2":{"start":"09:00:00","end":"09:50:00"},
             "ora3":{"start":"10:00:00","end":"10:50:00"},
             "....":{"start":"11:10:00","end":"12:00:00"},
             "oran":{"start":"12:10:00","end":"13:00:00"}
            }
     }
}

我们将不胜感激任何形式的帮助。 谢谢动态

【问题讨论】:

  • 您对传入格式有任何灵活性吗?还是您需要遵守该 EXACT 结构?

标签: json asp.net-mvc-3 model


【解决方案1】:

我很想知道是否可以让自定义模型绑定器适用于您的场景。下面是一个非常粗略的示例,适用于您的传入数据。请注意它需要很多改进,但确实绑定成功:

给定以下视图模型:

public class OraFormData
{
    public IDictionary<string, Duration> form { get; set; }
}

public class Duration
{
    public string Start { get; set; }
    public string End { get; set; }
}

使用此自定义模型绑定器:

public class OraFormDataModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        const string FORMKEY = "form[0][{0}][{1}]";
        const string PREFIX = "form[0][";

        try
        {
            var form = controllerContext.HttpContext.Request.Form;

            var vm = new OraFormData();

            var oraKeys = (from mainKey in form.AllKeys
                           where mainKey.StartsWith(PREFIX)
                           let trimmedKey = mainKey.Replace(PREFIX, String.Empty)
                           select trimmedKey.Substring(0, trimmedKey.IndexOf(']'))).Distinct().ToList();

            vm.form = new Dictionary<string, Duration>(oraKeys.Count);
            foreach (var oraKey in oraKeys)
            {
                vm.form.Add(oraKey, new Duration
                                        {
                                            Start = form[string.Format(FORMKEY, oraKey, "start")],
                                            End = form[string.Format(FORMKEY, oraKey, "end")]
                                        });
            }

            return vm;
        }
        catch
        {
            return null;
        }
    }
}

使用第一个示例中的字符串时会绑定以下操作:

[HttpPost]
public ActionResult TestPost([ModelBinder(typeof(OraFormDataModelBinder))]OraFormData form)
{
    // added modelbinder here just for example, could move to global.asax
    return Json(...);
}

【讨论】:

  • 谢谢你uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu!!!!肖恩,如果你遇到阿尔巴尼亚,我给你一杯啤酒。
【解决方案2】:

根据this post 中的答案,本机不支持绑定到您概述的 Dictionary 对象。但是,同一问题的其中一个答案显然创建了一个自定义 ModelBinder 来实现所需的结果。

如果你对传入的 json 数据有更多的控制权,你可以这样做:

public class OraViewModel
{
    public IList<LineItem> LineItems { get; set; }
}

public class LineItem
{
    public string Name { get; set; }
    public Duration Duration { get; set; }
}

public class Duration
{
    public string Start { get; set; }
    public string End { get; set; }
}

那么在你看来,你会这样发布:

$('#buttonId').click(function () {

    var data = { LineItems: [{ Name: "name 0", Duration: { Start: "start 0", End: "end 0"} }, { Name: "name 1", Duration: { Start: "start 1", End: "end 1"} }, { Name: "name 2", Duration: { Start: "start 2", End: "end 2"} }, { Name: "name 3", Duration: { Start: "start 3", End: "end 3"} }, { Name: "name 4", Duration: { Start: "start 4", End: "end 4"}}] };

    $.ajax({
        url: "/home/testpost2",
        data: JSON.stringify(data),  //*** using JSON2.js to stringify the js object
        type: "POST",
        contentType: 'application/json',   // *** note the content type is set to json
        dataType: 'json',
    });
});

这样做允许以下控制器操作正确地将传入数据绑定到我的对象:

[HttpPost]
public ActionResult TestPost2(OraViewModel data)
{
    return Json("whatever you want the return to be");
}

【讨论】:

  • 抱歉,现在我明白了您所说的灵活格式的意思。我正在使用 form2js (code.google.com/p/form2js) 来收集输入数据。我不确定在哪里可以从 form2js 实现建议的 json 格式,我会看看。谢谢
  • 如果您还没有看到,这里是另一个参考:hanselman.com/blog/…
  • 是的,我已经看到了,但我无法生成那种 html。我放弃了模型投标。我将尝试用 Json.net 解析它。再次感谢!!!
猜你喜欢
  • 1970-01-01
  • 2013-04-24
  • 1970-01-01
  • 2014-05-14
  • 2021-03-17
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
相关资源
最近更新 更多