C# 用于字段的ASP.NET MVC内联帮助器
我需要一个通用的内联帮助程序来显示字段 以下是我目前的情况:C# 用于字段的ASP.NET MVC内联帮助器,c#,asp.net-mvc,razor,html-helper,expression-trees,C#,Asp.net Mvc,Razor,Html Helper,Expression Trees,我需要一个通用的内联帮助程序来显示字段 以下是我目前的情况: @helper DisplayField(Func<MyModel, string> field) { if (string.IsNullOrWhiteSpace(field(Model)) == false) { <div class="row"> @field(Model) </div> } } 我不知道如何在助手内部显示标签(DisplayA
@helper DisplayField(Func<MyModel, string> field)
{
if (string.IsNullOrWhiteSpace(field(Model)) == false)
{
<div class="row"> @field(Model) </div>
}
}
我不知道如何在助手内部显示标签(DisplayAttribute)。请帮助。@David_001为此提供了一个非常优雅的MVC解决方案;我在这里留下我的答案,因为它描述了内部机制,如果您需要解决MVC开箱即用帮助程序未涵盖的问题,它可能会有所帮助。
将参数类型从
Func
更改为Expression
。通过这种方式,您可以在可以分析的方法中接收动态表达式,而不是在当前表单中接收的静态委托。您可以如下方式检索字段的值:
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();
您可以访问动态表达式返回的成员及其属性,如下所示:
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中是否有效;但我相信您也可以将代码移动到普通类。
请注意,由于调用者可以为方法提供多种动态表达式,因此这种方法会导致一些类型安全性的缺失。因此,如果您分析表达式以查找属性,则应该考虑这一点。在页面顶部,添加一个using for System.Linq.Expressions,例如
@using System.Linq.Expressions
(或在web.config中添加此命名空间)
然后,要创建辅助对象,它将如下所示:
@helper DisplayField(Expression<Func<MyModel, string>> field)
{
@Html.LabelFor(field)
@Html.DisplayFor(field)
}
等等。您可能需要在页面上检查您的使用情况,或者将HtmlHelper的名称空间添加到web.config中。这几乎是我所需要的,此外,如果它不是字符串,则无法工作
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());
}
}
}
@Html.DisplayFieldFor(m => m.Name)
@Html.DisplayFieldFor(m => m.PhoneNumber)