是否可以使用Razor创建通用的@helper方法?

mke*_*bbs 86 generics asp.net-mvc razor asp.net-mvc-3

我正在尝试在Razor中编写一个如下所示的帮助器:

@helper DoSomething<T, U>(Expression<Func<T, U>> expr) where T : class
Run Code Online (Sandbox Code Playgroud)

不幸的是,解析器认为这<T是HTML元素的开头,我最终会出现语法错误.是否可以使用Razor创建一个通用方法的帮助器?如果是这样,语法是什么?

小智 123

有可能实现与一个帮助文件中@functions的语法,但如果你想你指的是你的剃须刀式的可读性也需要调用一个常规帮手做HTML适应和完成.

请注意,Helper文件中的函数是静态的,因此如果您打算使用其方法,仍需要从页面传入HtmlHelper实例.

例如Views\MyView.cshtml:

@MyHelper.DoSomething(Html, m=>m.Property1)
@MyHelper.DoSomething(Html, m=>m.Property2)
@MyHelper.DoSomething(Html, m=>m.Property3)
Run Code Online (Sandbox Code Playgroud)

App_Code文件\ MyHelper.cshtml:

@using System.Web.Mvc;
@using System.Web.Mvc.Html;
@using System.Linq.Expressions;
@functions
{
    public static HelperResult DoSomething<TModel, TItem>(HtmlHelper<TModel> html, Expression<Func<TModel, TItem>> expr)
    {
        return TheThingToDo(html.LabelFor(expr), html.EditorFor(expr), html.ValidationMessageFor(expr));
    }
}
@helper TheThingToDo(MvcHtmlString label, MvcHtmlString textbox, MvcHtmlString validationMessage)
{
    <p>
        @label
        <br />
        @textbox
        @validationMessage
    </p>
}
...
Run Code Online (Sandbox Code Playgroud)

  • @Sheepy,这只是半真的.你是对的,你可以使它们非静态,但你只能得到`System.Web.WebPages.Html.HtmlHelper`而不是`System.Web.Mvc.HtmlHelper`.由于大多数扩展方法是针对`System.Web.Mvc.HtmlHelper`编写的,因此"WebPages"版本很可能不适合您.此外,没有`Url`属性,`UrlHelper`需要`RequestContext`,它在`WebPages`版本中不可用.总而言之,你可能不得不传入`Mvc``HtmlHelper`. (12认同)

Dar*_*rov 50

不,这是不可能的.您可以编写一个普通的HTML帮助程序.

public static MvcHtmlString DoSomething<T, U>(
    this HtmlHelper htmlHelper, 
    Expression<Func<T, U>> expr
) where T : class
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后:

@(Html.DoSomething<SomeModel, string>(x => x.SomeProperty))
Run Code Online (Sandbox Code Playgroud)

或者如果您将模型作为第一个通用参数进行定位:

public static MvcHtmlString DoSomething<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper, 
    Expression<Func<TModel, TProperty>> expr
) where T : class
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这将允许你像这样调用它(当然假设你的视图是强类型的,但这是一个安全的假设,因为所有的视图都应该是强类型的:-)):

@Html.DoSomething(x => x.SomeProperty)
Run Code Online (Sandbox Code Playgroud)

  • 希望这是他们为未来版本的Razor助手添加的东西.传统助手的可读性远低于@helper语法. (10认同)
  • 是的,同意了.恢复旧方法不仅糟糕,而且任意分裂你的助手! (2认同)