繁体   English   中英

用于字段的ASP.NET MVC内联帮助器

[英]ASP.NET MVC inline helper for fields

我需要一个通用的内联帮助器来显示字段。

这是我目前的情况:

@helper DisplayField(Func<MyModel, string> field)
{
    if (string.IsNullOrWhiteSpace(field(Model)) == false)
    {
        <div class="row"> @field(Model) </div>     
    }
}

用法:

@DisplayField(m => m.Name)
@DisplayField(m => m.PhoneNumber)

我不知道如何在帮助器中显示Label(DisplayAttribute)。 请帮忙。

在页面顶部,添加for for System.Linq.Expressions,例如。

@using System.Linq.Expressions

(或在web.config中添加此命名空间)。

然后创建帮助器,它看起来像:

@helper DisplayField(Expression<Func<MyModel, string>> field)
{
    @Html.LabelFor(field)
    @Html.DisplayFor(field)
}

你可以在那里添加额外的逻辑来检查空值等。你可能最好创建一个HtmlHelper,这样你可以使用泛型类型参数而不是上面的“MyModel”和“string”。 当我上次尝试时,无法将内联类型参数添加到内联帮助程序,例如。 以下是不可能的,除非这个功能已经添加:

@helper DisplayField<TModel, TValue>(Expression<Func<TModel, TValue>> field)
{
    @Html.LabelFor(field)
    @Html.DisplayFor(field)
}

因此,要获得泛型方法,您将使用自定义HtmlHelper。 去做这个:

  1. 创建如下文件:

     using System; using System.Linq; using System.Linq.Expressions; using System.Web; using System.Web.Mvc; using System.Web.Mvc.Html; namespace MvcApplication1.HtmlHelpers { public static class HtmlHelpers { public static MvcHtmlString DisplayFieldFor<TModel, TValue>( this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> field) { var labelString = helper.LabelFor(field); var displayString = helper.DisplayFor(field); return MvcHtmlString.Create( labelString.ToString() + displayString.ToString()); } } } 
  2. 在您的页面中,这样的事情的用法将是:

     @Html.DisplayFieldFor(m => m.Name) @Html.DisplayFieldFor(m => m.PhoneNumber) 

您可能需要检查页面上的使用情况或将HtmlHelper的名称空间添加到web.config中。

@ David_001为此提供了一个非常优雅的MVC解决方案; 我在这里留下我的答案,因为它描述了内部机制,如果您需要解决MVC开箱即用助手未涵盖的问题,可能会有所帮助。

将参数类型从Func<MyModel, string>更改为Expression<Func<MyModel, string>> 这样,您可以在方法中接收动态表达式,而不是在当前表单中收到的静态委托。
您可以像这样检索字段的值:

var compExpr = field.Compile();
var value = compExpr.DynamicInvoke(Model);

您可以访问动态表达式返回的成员及其属性,如下所示:

var memberAccExpr = (System.Linq.Expressions.MemberAccessExpression)field.Body;
var attr = (DisplayAttribute)memberAccExpr.Member.GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault();

我在C#项目(不是MVC)中大致测试过,所以我不能说它是否在Razor中有效; 但我相信你也可以把你的代码转移到正常的类。
请注意,使用此方法可以避免某种类型的安全性,因为调用者可以为该方法提供各种动态表达式。 因此,如果分析表达式以便查找属性,则应考虑到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM