我在创建将绑定到下面的表单数据的模型时遇到问题。我遇到的主要困难是创建一个绑定filter
的模型(即:多维数组)。
这是我到目前为止所拥有的。谁能帮助我让这个模型正确绑定?
public class GetPagedRequest
{
public int Start { set; get; }
public int Limit { set; get; }
public string dir { set; get; }
public List<FilterRequest> filter { set; get; } //This won't bind properly
}
public class FilterRequest
{
public string field { set; get; }
public DataFilterRequest data { set; get; }
}
public class DataFilterRequest
{
public string type { set; get; }
public string value { set; get; }
}
答案 0 :(得分:0)
在阅读DefaultModelBinder的功能后,我在帖子数据中看到了问题。
在此之前,只需将filter属性的类更改为:
public IList<FilterRequest> filter { set; get; } //(IList<T> instead of List<T>)
这是DefaultModelBinder将正确绑定的查询字符串:
start=0&limit=5&dir=ASC&sort=noSort&filter[0].field=CompanyName&filter[0].data.type=string&filter[0].data.value=Telus&filter[1].field=VendorName&filter[1].data.type=string&filter[1].data.value=testtest
但是js正在生成此查询字符串:
start=0&limit=5&dir=ASC&sort=noSort&filter[0][field]=CompanyName&filter[0][data][type]=string&filter[0][data][value]=Telus&filter[1][field]=VendorName&filter[1][data][type]=string&filter[1][data][value]=testtest
现在您可以实现自己的ModelBinder类,但我认为更容易在客户端序列化对象,只需确保正确设置内容类型。这是jquery中的一个例子:
<script type="text/javascript">
$(function () {
$("#btnSendPost").click(function () {
var filterData = {
"start": 0, "limit": 5,
"dir": "ASC", "sort": "noSort",
"filter": [{ "field": "CompanyName", "data": { "type": "string", "value": "Telus" } },
{ "field": "VendorName", "data": { "type": "string", "value": "testtest" } }]};
$.ajax({
type: "POST",
url: "/Home/ReceivePostFromJson",
data: JSON.stringify(filterData),
dataType: "json",
contentType: 'application/json; charset=utf-8'
});
});
});
</script>
然后,您只需将此行添加到global.asax文件中的Application_Start方法:
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
这样框架将正确绑定模型,并且在操作方法中,您将收到对象
[HttpPost]
public ActionResult ReceivePostFromJson(GetPagedRequest g)
{
如果您可以在发布过滤器数据之前对控件中的json进行String化,那么您可以使用JavaScriptSerializer对对象进行反序列化。
此示例在jquery中生成:
<script type="text/javascript">
$(function () {
$("#btnSendPost").click(function () {
var filterData = {
"start": 0, "limit": 5,
"dir": "ASC", "sort": "VendorName",
"filter": [{ "field": "CompanyName", "data": { "type": "string", "value": "Telus" } },
{ "field": "VendorName", "data": { "type": "string", "value": "testtest" } }]};
$.ajax({
type: "POST",
url: "/Home/ReceivePostFromJson",
data: JSON.stringify(filterData),
dataType: "application/json"
});
});
});
</script>
然后在控制器中:
[HttpPost]
public ActionResult ReceivePostFromJson()
{
string jsonStringify = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
var obj = new JavaScriptSerializer().Deserialize<GetPagedRequest>(jsonStringify);
return View(obj);
}
这样你就拥有了嵌套对象:
注意:在此示例中,如果您删除函数JSON.stringify (data:filterData,),您将在控制器端看到产生问题的查询字符串(filter [0] [field]:CompanyName)。我不知道是否有办法恢复json,如果有可能那么你不必修改网格控件:
答案 1 :(得分:0)
我不支持jherrera的解决方案:
[HttpPost]
public ActionResult ReceivePostFromJson()
{
string jsonStringify = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
var obj = new JavaScriptSerializer().Deserialize<GetPagedRequest>(jsonStringify);
return View(obj);
}
如果要从服务器端的客户端接收json数据,则应准备客户端对象以使其具有类似服务器端viewmodel的保存结构。这样,模型绑定器将在提交表单时完美地完成其工作。
未经测试的代码:
public ActionResult DeleteXXX(GetPagedRequest pagedRequestViewModel)
{
// Use AutoMapper or a UI Service to reshape/map your viewmodel to your domain model
return EmptyResult();
}