我在实现自定义模型绑定器进行验证方面找到了很多信息,但我并没有看到太多关于我要尝试做的事情。
我希望能够根据视图模型属性上的属性来操作模型绑定器将要设置的值。 例如:
public class FooViewModel : ViewModel
{
[AddBar]
public string Name { get; set; }
}
AddBar只是
public class AddBarAttribute : System.Attribute
{
}
我一直找不到一种简洁的方法,在自定义模型绑定器的BindModel方法中查找视图模型属性上的属性。虽然这个方法可以工作,但感觉应该有更简单的解决方案:
public class FooBarModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = base.BindModel(controllerContext, bindingContext);
var hasBarAttribute = false;
if(bindingContext.ModelMetadata.ContainerType != null)
{
var property = bindingContext.ModelMetadata.ContainerType.GetProperties()
.Where(x => x.Name == bindingContext.ModelMetadata.PropertyName).FirstOrDefault();
hasBarAttribute = property != null && property.GetCustomAttributes(true).Where(x => x.GetType() == typeof(AddBarAttribute)).Count() > 0;
}
if(value.GetType() == typeof(String) && hasBarAttribute)
value = ((string)value) + "Bar";
return value;
}
}
有没有更简洁的方法来查看视图模型属性上的属性,或者我可以使用不同种类的属性吗?数据注释属性似乎真的是针对不同的问题。更新
Craig的答案让我找到了正确的位置,但我想在这里放一些示例供其他人参考。
我最终得到的元数据提供程序如下:
public class FooBarModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
{
var metaData = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if(attributes.OfType<AddBarAttribute>().Any())
metaData.AdditionalValues.Add("AddBarKey", true);
return metaData;
}
}
模型绑定器的样子如下:
public class FooBarModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = base.BindModel(controllerContext, bindingContext);
if(bindingContext.ModelMetadata.AdditionalValues.ContainsKey("AddBarKey"))
value = ((string)value) + "Bar";
return value;
}
}