mvc之Action方法,参数为集合时的数据绑定

  mvc框架里面,Action方法的参数绑定是一个很重要的概念,而框架自带的默认绑定方式是不支持绑定集合类的参数的。

  不过不用担心,我们可以基于IModelBinder接口进行自定义的参数绑定,下面是一个绑定List类型参数的小例子,废话不多说,上代码

public class ArrayBind<T> : IModelBinder where T : class,new()
    {
        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)
        {
            List<T> list = new List<T>();
            string[] allKey = controllerContext.HttpContext.Request.Form.AllKeys;
            string newKey = "";
            string oldKey = "";
            T entity = new T();
            T beginEntity = entity;
            PropertyInfo[] infos = typeof(T).GetProperties();
            foreach (string key in allKey)
            {
                if (!key.StartsWith(bindingContext.ModelName, StringComparison.CurrentCultureIgnoreCase))
                {
                    continue;
                }
                int index = key.LastIndexOf('[');
                if (index < 0)
                    continue;
                newKey = key.Substring(0, index);
                if (string.IsNullOrEmpty(oldKey))
                    oldKey = key.Substring(0, index);
                if (newKey != oldKey)
                {
                    list.Add(entity);
                    entity = new T();
                    oldKey = newKey;
                }
                string currentKey = key.Substring(index);
                currentKey = currentKey.Replace("]", "").Replace("[", "");
                var obj = bindingContext.ValueProvider.GetValue(key);
                PropertyInfo info = infos.Where(p => p.Name == currentKey).FirstOrDefault();
                if (info != null)
                {
                    if (info.PropertyType.IsEnum)//不处理枚举
                        continue;
                    object value = null;
                    if (info.PropertyType.Name.Contains("Nullable"))
                    {
                        Type type = typeof(Nullable<>);
                        var types = info.PropertyType.GetGenericArguments();
                        Type runningType = type.MakeGenericType(types);
                        string a = ((string[])obj.RawValue)[0];
                        object argument = Convert.ChangeType(a, types[0]);
                        if (string.IsNullOrEmpty(a))
                            value = null;
                        else
                            value = Activator.CreateInstance(runningType, new object[] { argument }, null);
                    }
                    else
                    {
                        string str = ((string[])obj.RawValue)[0];
                        if (info.PropertyType.IsValueType && string.IsNullOrEmpty(str))
                            value = 0;
                        else
                        {
                            if (info.PropertyType == typeof(Guid))
                            {
                                Guid gid = Guid.Empty;
                                Guid.TryParse(str, out gid);
                                value = gid;
                            }
                            else
                                value = Convert.ChangeType(str, info.PropertyType);
                        }
                    }
                    info.SetValue(entity, value, null);
                }
            }
            if (!beginEntity.Equals(entity))
                list.Add(entity);
            return list;
        }
        #endregion
    } 

  action方法的写法是:

public ActionResult Record([ModelBinder(typeof(ArrayBind<PersonEntity>))]List<PersonEntity> persons)
        {
            object result = null;
            if (persons != null && persons.Count > 0)
                result = new { success = true };
            else
                result = new { success = false };
            return Json(result);
        }

  其中的PersonEntity是一个自定义的Model实体,前端采用的是post方式提交,传递参数的方式是json,格式是:{persons:[{Name:"张三",Age:18},{Name:"王五",Age:20}]},代码如下:

var data = [];
            for (var i = 0; i < 5; i++) {
                var json = { Name: "张三" + i.toString(), Age: 18 + i, Sex: (i % 2 == 0 ? "男" : "女") };
                if (i % 2 == 0) {
                    json.Birthday = "1998-10-25";
                }
                data.push(json);
            }
            $.ajax({
                url: "/Home/Record",
                type: "post",
                data: { persons: data },
                dataType:"json",
                success: function (result) {
                    alert(result.success);
                }
            });

  捕捉提交的请求,发现其提交的数据格式为:

posted @ 2016-10-25 19:10  尋找一個證明  阅读(902)  评论(0编辑  收藏  举报