从导航属性获取元数据

时间:2014-06-21 18:12:07

标签: c#

我想知道在ModelMetadataProviders类的帮助下是否有更好的方法来获取导航属性元数据值?

cshtml示例:

@model IEnumerable<WebApp.Web.Service.OfficeService.PlayerDeposit>

<div id="pagedList">
    <table class="table Report tablesorter table-bordered table">
        <thead>
            <tr>
                <th class="table-head sortTable">@Html.DisplayColumnNameFor(Model, m=> m.PaymentProvider.Name)
                </th>
                <th class="table-head sortTable">@Html.DisplayColumnNameFor(Model, m=> m.Country.CountryName)
                </th>
                <th class="table-head sortTable">@Html.DisplayColumnNameFor(Model, m=> m.NumberOfPlayers)
                </th>
                <th class="table-head sortTable">@Html.DisplayColumnNameFor(Model, m=> m.AmountDeposited)
                </th>
                <th class="table-head sortTable">@Html.DisplayColumnNameFor(Model, m=> m.Collected)
                </th>
                <th class="table-head sortTable">@Html.DisplayColumnNameFor(Model, m=> m.TransactionFee)
                </th>
                <th class="table-head sortTable">Balance
                </th>
                <th></th>
            </tr>
        </thead>

因此,为了获取元数据名称,我必须使用ModelMetadataProviders类创建视图助手。

我无法找到直接的方法来访问所提供实体名称的导航属性名称,所以我不得不使用旧的字符串操作(我知道lil mess):

 public static IHtmlString DisplayColumnNameFor<TModel, TClass, TProperty>
    (this HtmlHelper<TModel> helper, IEnumerable<TClass> model,
    Expression<Func<TClass, TProperty>> expression)
        {
            string entity = "";
            string name = "";
            ModelMetadata metadata = null;

            var expressionText = ExpressionHelper.GetExpressionText(expression);
            name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expressionText);

            if (name.Contains('.'))
            {
                int indexOfDot = name.IndexOf('.');

                entity = name.Substring(0, indexOfDot);
                name = name.Substring(indexOfDot + 1, name.Length - (indexOfDot + 1));

                Type classType = Type.GetType("WebApp.Web.Service.OfficeService." + entity);

                metadata =
                    ModelMetadataProviders
                        .Current
                        .GetMetadataForProperty(() => Activator.CreateInstance(classType), classType, name);
            }
            else
            {
                metadata = ModelMetadataProviders.Current.GetMetadataForProperty(
                    () => Activator.CreateInstance<TClass>(), typeof(TClass), name);
            }

            return new MvcHtmlString(metadata.DisplayName);
        }

正如你所看到的,因为我不知道是否有更好的方法直接从表达式访问导航属性我首先将实体和名称分开(我只计算一级深度导航属性)然后用反思的帮助我得到了类类型,所以我可以访问实体元数据......

我在html中尝试使用旧的hack作为实例化PlayerDeposit,然后直接在html中使用@Html.DisplayNameFor的模型,但由于某种原因,它不允许我(ambigious error):{{1} }。

1 个答案:

答案 0 :(得分:1)

我认为正确的做法是使用ModelMetadata.FromLambdaExpression。重要的是要注意,对于此应用程序,传递给ViewDataDictionary的{​​{1}}不会用于任何事情,因为我们不需要检查视图数据值。我们从属性本身获取显示名称。通过允许我们创建正确键入的FromLambdaExpression来进行调用,这使得相对容易。

ViewDataDictionary