在MVC3控制器中绑定复杂json模型的问题

时间:2013-05-14 16:23:09

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

我一直在努力让这篇文章在我的项目中发挥作用。基本上,我将一个安装对象列表(一个安装对象包含一个Facility对象列表)传递给我的控制器。我还没有得到绑定才能成功运行。我已经能够获得列表项的计数以反映传递给控制器​​的项目数,但是没有在单个对象中设置任何属性。

以下是执行帖子的代码:

$("#OpenFacilityResults").button().click(function () {
  var installHolder = {
    InstallList: []
  }
  var foundInstall = false
  $('.FullExport').each(function () {
    //var Install = { InstallRecnum: 0, FacilityList: [Facility, Facility] }
    //var Facility = { ID: 0, Product: 0 }
    if ($(this).prop('checked')) {
      var substr = $(this).parent().find('input:hidden').val().split('|');
      var fac = {
        ID: substr[1],
        Product: substr[2]
      }
      foundInstall = false
      $.each(installHolder.InstallList, function (index, value) {
        if (value.InstallRecnum == substr[0]) {
          foundInstall = true
          installHolder.InstallList[index].FacilityList.push(fac);
        }
      });
      if (foundInstall == false) {
        var i = {
          InstallRecnum: substr[0],
          FacilityList: []
        }
        i.FacilityList.push(fac)
        installHolder.InstallList.push(i)
      }
    }
  });
  console.log(JSON.stringify(installHolder));
  var dataHolder = JSON.stringify(installHolder)
  $.ajax({
    url: '@Url.Action("ViewFacilityDetails", "CHI")',
    type: 'POST',
    dataType: 'json',
    data: dataHolder,
    contentType: 'application/json',
    success: function (data) {
      // get the result and do some magic with it
    }
  });
});

这是JSON的样子:

{"InstallList":[{"InstallRecnum":"140","FacilityList":[{"ID":"0","Product":"1"}]},{"InstallRecnum":"138","FacilityList":[{"ID":"0","Product":"1"}]}]}

以下是控制器操作:

Function ViewFacilityDetails(ByVal InstallList As List(Of InstallInputModel)) As ActionResult
    Return Json(InstallList)
End Function

我试图绑定的对象:

<Serializable()> _
Public Class InstallInputModel
    Public InstallRecnum As Integer
    Public FacilityList As List(Of FacilityInputModel)
End Class
<Serializable()> _
Public Class FacilityInputModel
    Public ID As Integer
    Public Product As Integer
End Class

非常感谢任何帮助 - 提前感谢!

更新

以下是完成此任务的工作代码:

自定义模型绑定器:

Public Class JsonBinder
    Implements IModelBinder

    Public Function BindModel(controllerContext As System.Web.Mvc.ControllerContext, bindingContext As System.Web.Mvc.ModelBindingContext) As Object Implements System.Web.Mvc.IModelBinder.BindModel
        If controllerContext Is Nothing Then
            Throw New ArgumentNullException
        End If
        If bindingContext Is Nothing Then
            Throw New ArgumentNullException
        End If

        Dim request = controllerContext.HttpContext.Request

        request.InputStream.Seek(0, IO.SeekOrigin.Begin)
        Dim jsonString = New StreamReader(request.InputStream).ReadToEnd

        If Not jsonString Is Nothing Then

            Dim deserializer As New System.Web.Script.Serialization.JavaScriptSerializer
            Dim result = deserializer.Deserialize(Of InstallInputModelHolder)(jsonString)

            Return result
        Else
            Return Nothing
        End If

    End Function
End Class

* Gloabl.asax.vb添加*

ModelBinders.Binders.Add(GetType(InstallInputModelHolder), New JsonBinder())

我很可能会更改JSON,因此它只能传递数组,并且不需要额外的容器类来反序列化JSON。

1 个答案:

答案 0 :(得分:1)

创建一个ModelBinder,它将你的Jsonstring绑定到一个List(InstallInputModel)并在global.asax中注册它

脱离我的头顶(C#):

 public class JsonBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        //return base.BindModel(controllerContext, bindingContext);
        if (controllerContext == null)
        {
            throw new ArgumentNullException("controllerContext");
        }

        if (bindingContext == null)
        {
            throw new ArgumentNullException("bindingContext");
        }


        // Get the JSON data that's been posted
        var request = controllerContext.HttpContext.Request;

        request.InputStream.Seek(0, SeekOrigin.Begin);
        var jsonString = new StreamReader(request.InputStream).ReadToEnd();


        if (jsonString != null)
        {
            var serializer = new JavaScriptSerializer();
            var result = serializer.Deserialize(jsonString, typeof(List<InstallInputModel>));
            return result;

        }
        else
        {
            return null;
        }


    }
}

在Global.asax的Application_Start中,添加:

ModelBinders.Binders.Add(typeof(List<InstallInputModel>), new JsonBinder());