【问题标题】:Get Properties From Expression Func从表达式函数获取属性
【发布时间】:2019-09-24 15:46:12
【问题描述】:

我有一个为日期范围选择器输出 HTML 的扩展方法。

public static MvcHtmlString InputGroupDateRangePickerFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression) where TProperty : IDateRange

此扩展方法有一个通用属性TProperty,它有一个IDateRange 约束。 IDateRange 接口具有FromTo 属性。

我希望能够像这样访问每个 IDateRange 属性:

var html = $"<div class=\"input-daterange input-group\">
     {htmlHelper.TextBoxFor(expression.From)}
     {htmlHelper.TextBoxFor(expression.To)}</div>";

由于expression 参数是一个表达式函数,我无法访问这些属性。

我最初有两个表达式参数,一个用于From 属性,另一个用于To 属性。

Html.InputGroupDateRangePickerFor(x => x.Search.From, x => x.Search.To)

但我只想像这样传递IDateRange 对象

Html.InputGroupDateRangePickerFor(x => x.Search.DateRange)

【问题讨论】:

  • 为什么你有Expression&lt;Func&gt; 而没有Func
  • 我只是模仿了TextBoxFor参数

标签: c# html generics expression extension-methods


【解决方案1】:

可以改用编辑器模板:

Views/Shared/EditorTemplates/DateRange.cshtml

@model Services.Models.DateRange

<div class="col-md-12">
    <div class="form-group">
        @Html.LabelFor(m => m, new { @class = "m-b-none" })
        @Html.DescriptionFor(m => m)
        <div class="input-daterange input-group" style="width: 100%;">
            @Html.TextBoxFor(x => x.From, new{@class="form-control"})
            <span class="input-group-addon">to</span>
            @Html.TextBoxFor(x => x.To, new{@class="form-control"})
            <div class="input-group-addon validation-addon"><i class="fa fa-check-circle green-text validation"></i></div>
        </div>
        @Html.ValidationMessageFor(m => m, null, new { @class = "validation-message" })
    </div>
</div>

用法:

@Html.EditorFor(x => x.SearchCriteria.ExpectedDateOfDecisionRange)

或者为了使使用与您的其他扩展保持一致,您可以将其包装在一个函数中:

[StringFormatMethod("format")]
public static MvcHtmlString FormGroupDateRangePickerFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression, string format = "{0:dd/MM/yyyy}") where TProperty : IDateRange
{
    var html = $"{htmlHelper.EditorFor(expression)}";
    return new MvcHtmlString(html);
}

所以用法仍然是:

@Html.FormGroupDateRangePickerFor(x => x.SearchCriteria.ExpectedDateOfDecisionRange)

【讨论】:

    【解决方案2】:

    我通过抓取表达式主体然后使用它来创建 From 和 To 表达式字符串来实现它。然后我使用方法GetExpressionValue 获取IDateRange 值。

    var expressionBody = expression.Body.ToString().Split(new[] { '.' }, 2)[1];
    
    var fromExpressionBody = $"{expressionBody}.{nameof(IDateRange.From)}";
    var toExpressionBody = $"{expressionBody}.{nameof(IDateRange.To)}";
    
    var dateRangeValues = GetExpressionValue(htmlHelper, expression);
    

    然后我使用这些变量来生成 HTML。

    var html = $"<div class=\"input-daterange input-group\">
         {htmlHelper.TextBox(fromExpressionBody, dateRangeValues.From)}
         {htmlHelper.TextBox(toExpressionBody, dateRangeValues.To)}</div>";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多