2013-05-14 68 views
0

我一直在努力让这篇文章在我的项目中工作。基本上,我将一个Install对象列表(一个安装对象包含一个Facility对象列表)传递给我的控制器。我还没有让绑定成功工作。我已经能够获得列表项目的数量以反映传递给控制器​​的项目数量,但是没有任何属性正在单个对象中设置。在MVC3控制器中绑定复杂json模型的问题

以下是处理后的代码:

$("#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 

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

UPDATE

这里是工作的代码来实现:

自定义模型绑定:

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

创建将您Jsonstring结合(InstallInputModel的)的列表中ModelBinder的,并在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; 
     } 


    } 
} 

在Application_Start的Global.asax,加:

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

完美!这基本上就是它所需要的 - 当它反序列化但是自定义模型联编程序是解决方案时,我确实必须添加一个容器来容纳安装对象列表以匹配JSON。非常感谢您的帮助! – Skraps 2013-05-14 21:41:34