从表达式函数获取属性

问题描述 投票:2回答:2

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

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

此扩展方法具有具有TProperty约束的通用属性IDateRangeIDateRange接口具有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)
c# html generics expression extension-methods
2个回答
1
投票

可以改用编辑器模板:

查看/共享/ 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)

1
投票

我通过抓住表达式主体然后使用它来创建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>";
© www.soinside.com 2019 - 2024. All rights reserved.