有没有可能用Razor创build一个通用的@helper方法?
我正在试图写一个Razor的帮手,如下所示:
@helper DoSomething<T, U>(Expression<Func<T, U>> expr) where T : class
不幸的是,parsing器认为<T
是一个HTML元素的开始,我最终得到一个语法错误。 是否有可能用Razor创build一个通用方法的帮助器? 如果是这样,语法是什么?
不,这是不可能的。 你可以编写一个普通的HTML帮助器。
public static MvcHtmlString DoSomething<T, U>( this HtmlHelper htmlHelper, Expression<Func<T, U>> expr ) where T : class { ... }
接着:
@(Html.DoSomething<SomeModel, string>(x => x.SomeProperty))
或者如果您将模型作为第一个通用参数:
public static MvcHtmlString DoSomething<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expr ) where T : class { ... }
这将允许你像这样调用它(当然,假设你的视图是强types的,但是这是一个安全的假设,因为所有的视图都应该是强types的:-)):
@Html.DoSomething(x => x.SomeProperty)
这可以通过@functions
语法在帮助文件中实现,但是如果您想要的是指向您的razor式可读性,您还需要调用常规帮助器来完成HTML合并和完成。
请注意,Helper文件中的函数是静态的,所以如果您打算使用它的方法,您仍然需要从页面传入HtmlHelper实例。
例如Views \ MyView.cshtml:
@MyHelper.DoSomething(Html, m=>m.Property1) @MyHelper.DoSomething(Html, m=>m.Property2) @MyHelper.DoSomething(Html, m=>m.Property3)
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> } ...
在所有情况下, TModel
将是相同的(为视图声明的模型),在我的情况下, TValue
将是相同的,所以我能够声明Expression参数types:
@helper FormRow(Expression<Func<MyViewModel, MyClass>> expression) { <div class="form-group"> @(Html.LabelFor(expression, new { @class = "control-label col-sm-6 text-right" })) <div class="col-sm-6"> @Html.EnumDropDownListFor(expression, new { @class = "form-control" }) </div> @Html.ValidationMessageFor(expression) </div> }
如果你的模型字段都是string
,那么你可以用string
replaceMyClass
。
用定义的TValue
定义两个或三个助手可能并不坏,但是如果你还有更多的会产生一些难看的代码,我真的找不到一个好的解决scheme。 我尝试从@functions {}
块中放入一个函数来包装@helper
,但是我从来没有把它放在那个path上。
如果你的主要问题是使用lambdaexpression式来获取绑定的name属性值,就像@Html.TextBoxFor(x => x.MyPoperty)
,如果你的组件具有非常复杂的html标签,并且应该在剃刀助手上实现,那么为什么不要只是创build一个HtmlHelper<TModel>
的扩展方法来parsing绑定名称:
namespace System.Web.Mvc { public static class MyHelpers { public static string GetNameForBinding<TModel, TProperty> (this HtmlHelper<TModel> model, Expression<Func<TModel, TProperty>> property) { return ExpressionHelper.GetExpressionText(property); } } }
你的剃刀帮手应该像往常一样:
@helper MyComponent(string name) { <input name="@name" type="text"/> }
那么在这里你可以使用它
@TheHelper.MyComponent(Html.GetNameForBinding(x => x.MyProperty))
- 来自默认(EditorTemplates / DisplayTemplates)以外的文件夹的MVC模板?
- ASP.Net MVCredirect到一个不同的视图
- 带有List <BaseClass>和编辑器模板的ViewModel
- 如何在ASP.NET MVC应用程序中设置debugging启动页面?
- 我如何说服IE浏览器只显示应用程序/ JSON而不是提供下载?
- 在ASP.NET MVC Html.ActionLink中包含一个锚标签
- 为什么没有Guid.IsNullOrEmpty()方法
- 如何使用Ajax.ActionLink?
- 扩展AuthorizeAttribute覆盖AuthorizeCore或OnAuthorization