在模型绑定时在视图模型属性上查找自定义属性

在模型绑定时在视图模型属性上查找自定义属性

问题描述:

我发现了很多关于实现用于验证目的的自定义模型绑定器的信息,但我没有看到太多关于我正在尝试执行的操作。在模型绑定时在视图模型属性上查找自定义属性

我希望能够根据视图模型中属性的属性来操作模型联编程序要设置的值。例如:

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; 
    } 
} 

有没有查看视图模型属性或不同种类的属性我可以使用属性的更清洁的方式? DataAnnotation属性确实看起来是针对不同的问题。

UPDATE

克雷格的回答让我在正确的地方,但我想我会放一些例子在这里为别人着想。

我结束了看起来像

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; 
    } 
} 

“正确”的方式(每它是谁写的家伙)是write a model metadata provider。链接上有一个例子。不是“简单”,但它的工作原理,你会做MVC的其余部分。

+0

我认为这是有道理后,你的链接,但现在我不太确定。我实际上不想改变任何数据注释属性的值,而是根据新属性(通过在上面的示例中添加“Bar”到末尾)来更改模型本身的值。调用metaData.Model + =“Bar”似乎对任何事情都没有任何影响。 – Jared 2011-06-01 18:47:27

+0

将您的自定义标记添加到模型元数据后,您可以更改模型联编程序以识别它们。 – 2011-06-01 19:49:56

+2

感谢您的指针。我已根据您分享的链接更新了一些主要帖子。 – Jared 2011-06-03 12:49:06