模型绑定

什么是模型绑定?

  首先思考这个,如果在表单中输入了值,然后调用Index方法 

  

  其实这个有值,就是因为有模型绑定,那么模型绑定是怎么实现对象的创建以及赋值的呢?

    主要是实现IModelBinder这个接口,并实现BindModel()方法

      在这个方法里面,通过ModelBindingContext的ValueProvider的GetValue来获取值,那么值有哪些来源呢?

  ->1.Request.Form

  ->2.RouteData.values

  ->3.Request.QueryString

  ->4.Request.Files

  应用程序就在这些内置的集合中找值,下面来看一下一个简单的值提供者

    public class CurrentTimeValueProvider:IValueProvider
    {
        public bool ContainsPrefix(string prefix)
        {
            return string.Compare("CurrentTime",prefix,true)==0;
        }

        public ValueProviderResult GetValue(string key)
        {
            return ContainsPrefix(key) ? new ValueProviderResult(DateTime.Now, null, System.Globalization.CultureInfo.InstalledUICulture) : null;
        }
    }

  然后如果我们要使用这个值提供者,那么我们就应该让程序知道,我们有这个提供者

    所有,我们需要在全局处理程序Global.asax中的Application_Start()方法中注册

  为了注册我们还需要创建一个值提供者工厂

 

    public class CurrentTimeValueProviderFactory:ValueProviderFactory
    {
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            return new CurrentTimeValueProvider();
        }
    }

 

ValueProviderFactories.Factories.Add(new CurrentTimeValueProviderFactory());

  然后我们在控制器中访问

通过这个我们可以知道我们写的这个值提供者,只是简单的判断是否可以处理这个currentTime前缀的数据,如果可以就返回当前时间

  否则,返回空

既然我们有了值提供者,那么我们就可以通过模型绑定来获取值了,下面上一个例子

    public class Person
    {
        [HiddenInput(DisplayValue=false)]
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        [DataType(DataType.Date)]
        public DateTime BirthDate { get; set; }
        public Address HomeAddress { get; set; }
        public bool IsApproved { get; set; }
    }
    public class PersonModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            //获取要绑定的模型对象
            var model = (Person)bindingContext.Model ?? (Person)DependencyResolver.Current.GetService(typeof(Person));
            var hasPrefi = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
            var searchPrefix = (hasPrefi) ? bindingContext.ModelName + "." : "";
            model.PersonId = int.Parse(GetValue(bindingContext, searchPrefix, "PersonId"));
            model.FirstName = GetValue(bindingContext, searchPrefix, "FirstName");
            model.LastName = GetValue(bindingContext, searchPrefix, "LastName");
            model.BirthDate = DateTime.Parse(GetValue(bindingContext, searchPrefix, "BirthDate"));
            model.IsApproved = GetCheckedValue(bindingContext, searchPrefix, "IsApproved");
            return model;
        }
        private string GetValue(ModelBindingContext context, string prefix, string ke)
        {
            var vpr = context.ValueProvider.GetValue(ke);
            return vpr == null ? null : vpr.AttemptedValue;
        }
        private bool GetCheckedValue(ModelBindingContext context, string prefix, string ke)
        {
            var result = false;

            var vpr = context.ValueProvider.GetValue(prefix + ke);
            if (vpr != null)
            {
                result = (bool)vpr.ConvertTo(typeof(bool));
            }
            return result;
        }
    }

然后我们就需要我们这个模型绑定和程序关联起来了,关联的方法一共有三种

  ->1.

ModelBinders.Binders.Add(typeof(Person), new PersonModelBinder());

  ->2.和上面的值提供者一个,需要实现一个工厂接口 

ModelBinderProviders.BinderProviders.Add(new CustomModelBinderProvider());

  ->3.直接在类上面使用

[ModelBinder(typeof(PersonModelBinder))]

 

posted @ 2017-03-08 21:48  夏风微凉  阅读(1002)  评论(0编辑  收藏  举报