Mar*_*tin 4 model-binding asp.net-mvc-4
我的印象是,当绑定到复杂模型时,处理所有公共属性并尝试对每个属性进行匹配绑定.
我正在尝试解决变量命名问题以便建模
class Model {
public string Foo {get;set;}
public string FooBar {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
与查询字符串很好地配合使用
?foo=foo&foo_bar=foo_bar
Run Code Online (Sandbox Code Playgroud)
有没有比自定义模型绑定器更好的方法?无论如何,我的工作不起作用.简单地跳过了FooBar.
public class StringModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var model = base.BindModel(controllerContext, bindingContext);
if (model != null)
return model;
var modelName = Regex.Replace(bindingContext.ModelName, "([a-z])([A-Z])", "$1_$2").ToLowerInvariant();
var value = bindingContext.ValueProvider.GetValue(modelName);
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
注册
ModelBinders.Binders.Add(typeof(string), new StringModelBinder());
Run Code Online (Sandbox Code Playgroud)
Dar*_*rov 15
我的印象是,当绑定到复杂模型时,处理所有公共属性并尝试对每个属性进行匹配绑定.
不,这是一个错误的印象.默认模型绑定器将尝试仅绑定在Request中具有相应值的属性.在您的情况下,您没有FooBar属性的相应值,因此它不会被绑定.
实际上,如果我们能写出来会很好:
public class Model
{
public string Foo { get; set; }
[ParameterName("foo_bar")]
public string FooBar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以让我们实现这一点.我们首先编写一个基本属性:
[AttributeUsageAttribute(AttributeTargets.Property)]
public abstract class PropertyBinderAttribute : Attribute, IModelBinder
{
public abstract object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext);
}
Run Code Online (Sandbox Code Playgroud)
和自定义模型绑定器:
public class CustomModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
var propertyBinderAttribute = propertyDescriptor
.Attributes
.OfType<PropertyBinderAttribute>()
.FirstOrDefault();
if (propertyBinderAttribute != null)
{
var value = propertyBinderAttribute.BindModel(controllerContext, bindingContext);
propertyDescriptor.SetValue(bindingContext.Model, value);
}
else
{
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,此自定义模型分析模型的元数据,如果使用PropertyBinderAttribute的实例修饰属性,它将使用它.
然后我们将使用我们的自定义模板绑定器替换默认模型绑定器Application_Start:
ModelBinders.Binders.DefaultBinder = new CustomModelBinder();
Run Code Online (Sandbox Code Playgroud)
现在剩下的就是实现我们用来装饰我们的模型属性的ParameterNameAttribute绑定器:
public class ParameterNameAttribute : PropertyBinderAttribute
{
private readonly string parameterName;
public ParameterNameAttribute(string parameterName)
{
this.parameterName = parameterName;
}
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(this.parameterName);
if (value != null)
{
return value.AttemptedValue;
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1567 次 |
| 最近记录: |