Получить свойства из выражения Func

У меня есть метод расширения, который выводит HTML для выбора диапазона дат.

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

Этот метод расширения имеет общее свойство TProperty с ограничением IDateRange. Интерфейс IDateRange имеет свойства From и To.

Я хочу иметь доступ к каждому из свойств 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)

person Bad Dub    schedule 24.09.2019    source источник
comment
Почему у вас есть Expression<Func> и нет Func?   -  person HimBromBeere    schedule 24.09.2019
comment
Я просто имитировал параметры TextBoxFor   -  person Bad Dub    schedule 24.09.2019


Ответы (2)


Вместо этого можно использовать шаблон редактора:

Представления/Общие/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)
person Ciaran Gallagher    schedule 25.09.2019

Я заставил его работать, захватив тело выражения, а затем используя его для создания строк выражений 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>";
person Bad Dub    schedule 25.09.2019