今天把我在公司家园的一个试用小文转来这里与大家分享。 对正在Mvc实践开发的朋友很有用哦?
Asp.net Mvc Controller Json数组 接收 数组 字典 类型 复杂对象
方法一,(最复杂的方法)
扩展ModelBinder 完全自定义一种参数的解析方法。
/// <summary>
/// 模式绑定数组接收器 eg:,接收字符数组:参数标记如 [ModelBinder(typeof(ArrayBind<string>))]string[] arrayValue
/// </summary>
/// <typeparam name="T"></typeparam>
public class ArrayBind<T> : IModelBinder
{
private _T GetValue<_T>(ModelBindingContext bindingContext, string key)
{
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(key);
bindingContext.ModelState.SetModelValue(key, valueResult);
return (_T)valueResult.ConvertTo(typeof(_T));
}
#region IModelBinder 成员
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Dictionary<int, T> list = new Dictionary<int, T>();
string[] allKey = controllerContext.HttpContext.Request.Form.AllKeys;
foreach (string key in allKey)
{
if (!key.StartsWith(bindingContext.ModelName, StringComparison.CurrentCultureIgnoreCase))
{
continue;
}
string[] _key = key.Split('.');
if (_key.Length != 2)
{
continue;
}
int me = 0;
if (int.TryParse(_key[1], out me))
{
list.Add(me, GetValue<T>(bindingContext, key));
}
}
var sort = from k in list orderby k.Key ascending select k;
return sort.Select<KeyValuePair<int, T>, T>(C => C.Value).ToArray();
}
#endregion
}
然后在Controller的action方法参数中进行标记,如:
[HttpPost]
public ActionResult Edit([Bind(Prefix = "LevelDescription")][ModelBinder(typeof(ArrayBind<string>))]string[] levelOrder)
{
return Json(1);
}
方法二,url参数解析法
http://www.domain.com/post?levelOrder=1&levelOrder=2&levelOrder=3&levelOrder=4&levelOrder=5
不推荐这种方法,Url长度有限制,当需要通过URL传递的数据量较大时就会出现404错误,很恐怖哦。这个“bug”比较隐蔽
方法三,
接收复杂对象数组,Js异步提交数据,
var _lev = {};
_lev["lev[0].Status"] = "5"; //这里必须从零开始 名字必须一样
_lev["lev[1].Status"] = "6";
$.post("Edit", _lev
, function(json) {
if (json == "1") { alert(''成功)}
}, "json");
同步提交同理,需要在表单中构造这样的结构
<input type="text" name="lev[0].Status" value="5" /><input type="text" name="lev[1].Status" value="6" /> 这里会按照parameterName[index].PropertyName的规则来解析属性。其中,索引必须是连续的且以0开始的正整数。
action方法,如:
[HttpPost]
public ActionResult Edit(Level[] lev)
{
return Json(lev);
}
如果在action中欲接收一Dictionary 类型值,则变得更加方便,
$("tr[name = 'LeelArea']").each(function(index) {
_lev["levelOrder1[" + index + "].key"] = index; //这里必须从零开始 名字必须一样
_lev["levelOrder1[" + index + "].value"] = $(this).find("textarea").val();
});
if ($(this).valid()) {
$.post("Edit", _lev
, function(json) {
Alert(json);
}, "json");
}
这里解析key的方式是寻找parameterName[index].Key这样的结构、解析value的方式是寻找parameterName[index].Value这样的结构。如果key或者value是复杂类型(如上面例子中的Information类型),则parameterName[index].Key或parameterName[index].value将被视为前缀(也可以理解为某个类型)而.PropertyName被视为后缀(即某个属性)。这里的索引也要求必须是以0开始的不间断的正整数。否则断开以后的部分将不会被解析。
action方法,如:
[HttpPost]
public ActionResult Edit(Dictionary<int,string> levelOrder)
{
return Json(1);
}
整理思路参考:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
可能很多朋友还有其他更好的方法去解决这个问题,但是既然MVC已经帮我们考虑了一个这样的方式来传递复杂对象,为什么不使用呢?而且他是mvc自己的特性,不必担忧后期支持的问题和对象的解析性能问题。我现在的一个Mvc的项目,为增强体验,大量要求使用Ajax来处理数据,传递复杂对象到?Controller是一个比较高效的解决方案。扩展了“M?”到“C?”的视野。
?强烈推荐本文:.net Mvc Controller 接收 Json/post方式 数组 字典 类型 复杂对象?http://hi.baidu.com/yandavid/blog/item/8aef08dfa4afba026227987c.html
http://home.beisencorp.com/space.php?uid=210&do=blog&id=957
转载请表明来源,谢谢!