用于绑定此复杂嵌套json的正确模型是什么

时间:2011-12-07 12:29:35

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

我一直在努力在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"}
            }
     }
}

任何形式的帮助将不胜感激。 谢谢dynamicus

2 个答案:

答案 0 :(得分:2)

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

给出以下视图模型:

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(...);
}

答案 1 :(得分:1)

根据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");
}