.Net 模型通过 JSON post 绑定数据集
.Net Model binding a dataset via JSON post
我在这方面玩得很开心。我肯定错过了什么。
我正在通过 Angular/JSON 将复杂模型 post 连接到 .NET 控制器。当 post 将其返回到服务器时,DefaultModelBinder 仅部分绑定到模型(简单的值,如 int (ID) 和 string (title) 就可以了)。 "ListItems" 数据集以及属于 ProjectDetails 模型的 "ProductsList" 数据表似乎被忽略了。根据我正在阅读的内容,对于复杂的 objects DefaultModelBinder 递归地在 JSON 处进行第二次传递,然后映射它可以找到的 objects 。我尝试了很多通过搜索 Whosebug 找到的解决方案,但都无济于事。我想我在这一点上失去了我的观点。这是我所拥有的。任何帮助将不胜感激。
模特
Public Class ProjectDetails
Private _ListItems As DataSet
<JsonProperty("ListItems")> _
Public Property ListItems() As DataSet
Get
Return _ListItems
End Get
Set(ByVal value As DataSet)
_ListItems = value
End Set
End Property
Private _ProductsList As DataTable
Public Property ProductsList As DataTable
Get
Return _ProductsList
End Get
Set(value As DataTable)
_ProductsList = value
End Set
End Property
Private _imageID As Int32 = 0
Public Property imageID() As Int32
Get
Return _imageID
End Get
Set(ByVal value As Int32)
_imageID = value
End Set
End Property
Private _Title As String = String.Empty
Public Property Title() As String
Get
Return _Title
End Get
Set(ByVal value As String)
_Title = value
End Set
End Property
End Class
动作控制器
<Authorize()> _
<AcceptVerbs(HttpVerbs.Post)> _
<ValidateInput(False)> _
Async Function ProjectUpdate(ByVal d As ProjectDetails) As Task(Of JsonResult)
'send results to database here
Save(d)
return json(true)
End Function
Header
POST http://localhost:51110/projectUpdate HTTP/1.1
Host: localhost:51110
Connection: keep-alive
Content-Length: 10119
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
Content-Type: application/json;charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
JSON数据posted
{"ListItems":
{"ProjectStatusCodes":[{"id":1,"ProjectStatusTx":"Stage1 - Under Construction"},{"id":3,"ProjectStatusTx":"Stage3 - Project Released"},{"id":4,"ProjectStatusTx":"Project Closed"}],
"ProductsList":[
{"id":2336,"Name":"Product1","Description":"This is a description","$$hashKey":"00K"},
{"id":2337,"Name":"Product2","Description":"This is a second description","$$hashKey":"00M"}],
"imageID":345,
"Title":"books", }
}
AngularJS代码
$scope.update = function (formData) {
$http({
method: 'POST',
url: '/projectbuilder/projectUpdate',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify($scope.formData)
}).success(function (data, status, headers, config) {
$scope.codeStatus = status;
}).error(function (data, status, headers, config) {
$scope.codeStatus = status || "Request failed";
});
HTML 具有表单值的模板
<div ng-repeat="ProductsList in formData.ListItems.ProductsList">
<div>
<div>
<div>
<input value="{{ProductsList.Title}}" name="ProductsList.Title" ID="ProductsList.Title" ng-model="ProductsList.Title" >
<br />
<input value="{{ProductsList.ImageID}}" name="ProductsList.ImageID" ID="ProductsList.ImageID" ng-model="ProductsList.ImageID" >
</div>
</div>
</div>
行为
JSON post 对控制器工作正常,它绑定了 ImageID 和标题。 ListItems 数据集不包含表,并且 ListItems 数据集中的 ProductsList 数据表不存在。
注意:JSON 中的 ProjectStatusCodes 数据未映射回模型,因为它仅用于在表单上显示。
如果它试图将 "ListItems" 从您的 json 序列化为一个列表对象,它可能会导致问题,因为您的 json 中没有括号,即使它是列表中只有一个对象:
{"ListItems":[
{
"ProjectStatusCodes":[{"id":1,"ProjectStatusTx":"Stage1 - Under Construction"},{"id":3,"ProjectStatusTx":"Stage3 - Project Released"},{"id":4,"ProjectStatusTx":"Project Closed"}],
"ProductsList":[{"id":2336,"Name":"Product1","Description":"This is a description","$$hashKey":"00K"},{"id":2337,"Name":"Product2","Description":"This is a second description","$$hashKey":"00M"}],
"imageID":345,
"Title":"books"
}
]}
好的。我想到了。似乎 JSON.NET 在发送时很好地序列化了对象,确保它完全符合 JSON 标准。坏消息是在将数据表发送回 .NET 应用程序时,它删除了使数据表可反序列化的大部分内容。
我最后做的是在回发时捕获 JSON 字符串,并使用您可以在此处找到的 JSON.NET 片段序列化分别访问序列化数据表数据。 http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm 我留下了对象的其余部分 "as is" 并从 JSON 字符串中获取了数据表,并使用这种技术手动进行了反序列化。文章中的示例非常有用。
读取JSON字符串的代码
Dim req As Stream = Request.InputStream
req.Seek(0, System.IO.SeekOrigin.Begin)
Dim jsonstring As String = New StreamReader(req).ReadToEnd()
解析和反序列化的代码
Dim ProductsList As JObject = JObject.Parse(jsonstring)
Dim results As IList(Of JToken) = ProductsList("ListItems")("ProductsList").Children().ToList()
Console.Write(results)
不是很优雅,但很管用。
我在这方面玩得很开心。我肯定错过了什么。
我正在通过 Angular/JSON 将复杂模型 post 连接到 .NET 控制器。当 post 将其返回到服务器时,DefaultModelBinder 仅部分绑定到模型(简单的值,如 int (ID) 和 string (title) 就可以了)。 "ListItems" 数据集以及属于 ProjectDetails 模型的 "ProductsList" 数据表似乎被忽略了。根据我正在阅读的内容,对于复杂的 objects DefaultModelBinder 递归地在 JSON 处进行第二次传递,然后映射它可以找到的 objects 。我尝试了很多通过搜索 Whosebug 找到的解决方案,但都无济于事。我想我在这一点上失去了我的观点。这是我所拥有的。任何帮助将不胜感激。
模特
Public Class ProjectDetails
Private _ListItems As DataSet
<JsonProperty("ListItems")> _
Public Property ListItems() As DataSet
Get
Return _ListItems
End Get
Set(ByVal value As DataSet)
_ListItems = value
End Set
End Property
Private _ProductsList As DataTable
Public Property ProductsList As DataTable
Get
Return _ProductsList
End Get
Set(value As DataTable)
_ProductsList = value
End Set
End Property
Private _imageID As Int32 = 0
Public Property imageID() As Int32
Get
Return _imageID
End Get
Set(ByVal value As Int32)
_imageID = value
End Set
End Property
Private _Title As String = String.Empty
Public Property Title() As String
Get
Return _Title
End Get
Set(ByVal value As String)
_Title = value
End Set
End Property
End Class
动作控制器
<Authorize()> _
<AcceptVerbs(HttpVerbs.Post)> _
<ValidateInput(False)> _
Async Function ProjectUpdate(ByVal d As ProjectDetails) As Task(Of JsonResult)
'send results to database here
Save(d)
return json(true)
End Function
Header
POST http://localhost:51110/projectUpdate HTTP/1.1
Host: localhost:51110
Connection: keep-alive
Content-Length: 10119
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
Content-Type: application/json;charset=UTF-8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8
JSON数据posted
{"ListItems":
{"ProjectStatusCodes":[{"id":1,"ProjectStatusTx":"Stage1 - Under Construction"},{"id":3,"ProjectStatusTx":"Stage3 - Project Released"},{"id":4,"ProjectStatusTx":"Project Closed"}],
"ProductsList":[
{"id":2336,"Name":"Product1","Description":"This is a description","$$hashKey":"00K"},
{"id":2337,"Name":"Product2","Description":"This is a second description","$$hashKey":"00M"}],
"imageID":345,
"Title":"books", }
}
AngularJS代码
$scope.update = function (formData) {
$http({
method: 'POST',
url: '/projectbuilder/projectUpdate',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify($scope.formData)
}).success(function (data, status, headers, config) {
$scope.codeStatus = status;
}).error(function (data, status, headers, config) {
$scope.codeStatus = status || "Request failed";
});
HTML 具有表单值的模板
<div ng-repeat="ProductsList in formData.ListItems.ProductsList">
<div>
<div>
<div>
<input value="{{ProductsList.Title}}" name="ProductsList.Title" ID="ProductsList.Title" ng-model="ProductsList.Title" >
<br />
<input value="{{ProductsList.ImageID}}" name="ProductsList.ImageID" ID="ProductsList.ImageID" ng-model="ProductsList.ImageID" >
</div>
</div>
</div>
行为 JSON post 对控制器工作正常,它绑定了 ImageID 和标题。 ListItems 数据集不包含表,并且 ListItems 数据集中的 ProductsList 数据表不存在。
注意:JSON 中的 ProjectStatusCodes 数据未映射回模型,因为它仅用于在表单上显示。
如果它试图将 "ListItems" 从您的 json 序列化为一个列表对象,它可能会导致问题,因为您的 json 中没有括号,即使它是列表中只有一个对象:
{"ListItems":[
{
"ProjectStatusCodes":[{"id":1,"ProjectStatusTx":"Stage1 - Under Construction"},{"id":3,"ProjectStatusTx":"Stage3 - Project Released"},{"id":4,"ProjectStatusTx":"Project Closed"}],
"ProductsList":[{"id":2336,"Name":"Product1","Description":"This is a description","$$hashKey":"00K"},{"id":2337,"Name":"Product2","Description":"This is a second description","$$hashKey":"00M"}],
"imageID":345,
"Title":"books"
}
]}
好的。我想到了。似乎 JSON.NET 在发送时很好地序列化了对象,确保它完全符合 JSON 标准。坏消息是在将数据表发送回 .NET 应用程序时,它删除了使数据表可反序列化的大部分内容。
我最后做的是在回发时捕获 JSON 字符串,并使用您可以在此处找到的 JSON.NET 片段序列化分别访问序列化数据表数据。 http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm 我留下了对象的其余部分 "as is" 并从 JSON 字符串中获取了数据表,并使用这种技术手动进行了反序列化。文章中的示例非常有用。
读取JSON字符串的代码
Dim req As Stream = Request.InputStream
req.Seek(0, System.IO.SeekOrigin.Begin)
Dim jsonstring As String = New StreamReader(req).ReadToEnd()
解析和反序列化的代码
Dim ProductsList As JObject = JObject.Parse(jsonstring)
Dim results As IList(Of JToken) = ProductsList("ListItems")("ProductsList").Children().ToList()
Console.Write(results)
不是很优雅,但很管用。