2011-11-14 22 views
1

我试图获取与数组中的实例关联的元数据。我已经定义了一个在我的视图中调用的HtmlHelper扩展。我正在尝试创建一个帮助程序来显示模型列表和它们的错误消息。为特定实例获取ModelMetadata

@model Domain.Models.Customer 
@this.Html.Example(m => m.Orders) 

下面是这个实现我的助手

public static class HtmlHelperExtensions 
{ 
    public static IHtmlString Example<TModel, TInstance>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TInstance[]>> expression) 
    { 
     var instanceProvider = expression.Compile(); 
     var instances = instanceProvider.Invoke(helper.ViewData.Model); 

     if(instances != null) 
     { 
      var properties = typeof (TInstance).GetProperties(); 
      for(var i = 0; i < instances.Length; i++) 
      { 
       var instanceExpression = Expression.ArrayIndex(expression.Body, Expression.Constant(i)); 

       foreach(var info in properties) 
       { 
        var propertyExpression = Expression.Property(instanceExpression, info); 

        // How can i get access to the ModelMetadata 
        ModelMetadata.FromStringExpression(propertyExpression.ToString(), helper.ViewData); 

        // To get the model state we need the following... 
        var text = ExpressionHelper.GetExpressionText(Expression.Lambda(propertyExpression)); 
        var fieldName = helper.ViewData.TemplateInfo.GetFullHtmlFieldName(text); 

        ModelState state; 
        if(helper.ViewData.ModelState.TryGetValue(fieldName, out state)) 
        { 
         // Output errors.... 
        } 
       } 

      } 
     } 

     return MvcHtmlString.Empty; 
    } 
} 

的使用下面的领域类

public class Customer 
{ 
    public Order[] Orders { get; set; } 
} 

public class Order 
{ 
    public string Description { get; set; } 
} 

回答

0

据我知道它的不存在!

ModelMetadata将用于模型的属性,在这种情况下,数组本身的属性不是数组中的元素。

所以如果你需要ModelMetadata的数组中的元素,你将需要创建自定义模型元数据提供商,这将得到你需要的属性,并将它们添加到ModelMetadata,例如引导代码片段

public class ArrayMetadataProvider : 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); 

     // Add your metadata here 

     return metadata; 
    } 

} 

然后您需要注册以下服务提供商:

protected void Application_Start() 
    { 

     ModelMetadataProviders.Current = new ArrayMetadataProvider(); 

    }