MVC Model Binding 学习心得
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ValueProviderFactories.Factories.Insert(0, new CustomValueProviderFactory()); ModelBinders.Binders.Add(typeof(AddressSummary), new AddressSummaryBinder()); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
CustomValueProvider:
public class CountryValueProvider : IValueProvider { public bool ContainsPrefix(string prefix) { return prefix.ToLower().IndexOf("country") > -1; } public ValueProviderResult GetValue(string key) { if (ContainsPrefix(key)) { return new ValueProviderResult("USA", "USA", CultureInfo.InvariantCulture); } else { return null; } } }
public class CustomValueProviderFactory : ValueProviderFactory { public override IValueProvider GetValueProvider(ControllerContext controllerContext) { return new CountryValueProvider(); } }
Custom Model Binder
public class AddressSummaryBinder : IModelBinder { public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { AddressSummary model = (AddressSummary)bindingContext.Model ?? new AddressSummary(); model.City = GetValue(bindingContext, "City"); model.Country = GetValue(bindingContext, "Country"); return model; } private string GetValue(ModelBindingContext context, string name) { name = (context.ModelName == "" ? "" : context.ModelName + ".") + name; ValueProviderResult result = context.ValueProvider.GetValue(name); if (result == null || result.AttemptedValue == "") { return "<Not Specified>"; } else { return (string)result.AttemptedValue; } } }
这里要说明一下:context.ValueProvider.GetValue(name)里的ValueProvider是一个集合,调用GetValue的时候,实际上是尝试轮训所有的ValueProvider,如果第一次轮训的时候得到的值是null,那么下一次将会继续,直至轮训完所有的ValueProvider为止。
BindModel->ValueProviderCollection->ValueProvider->GetValue->UpdateModel