6

次のような 3 つの異なるセクションを含むフォームがあります。

<form action="/Submit/" method="POST">
    <h2>
        Your Info:
    </h2>
    <ul>
        <li>
            <label>
                First Name:
                @Html.TextBoxFor(m => m.FirstName)
            </label>
        </li>
        <li>
            <label>
                Last Name:
                @Html.TextBoxFor(m => m.LastName)
            </label>
        </li>
    </ul>
    <h2>
        Membership:
    </h2>
    <ul>
        <li>
            <label>@Html.RadioButtonFor(m => m.MembershipLength_Months, 3) 3 Months</label>
        </li>
        <li>
            <label>@Html.RadioButtonFor(m => m.MembershipLength_Months, 12) 12 Months</label>
        </li>
    </ul>
   <h2>
        Billing Info:
    </h2>
    @Html.EditorFor(m=> m.PaymentInfo)
    <input type="submit" value="Submit" />
</form>

私がやりたいのは、セクションごとに要約することです。各 H2 の下で次のようなことができることを知っています。

@if (ViewData.ModelState.Keys.Contains("FirstName") || ViewData.ModelState.Keys.Contains("LastName"))
{
    <div>
        summary text
        @Html.ValidationMessageFor(m => m.FirstName)
        @Html.ValidationMessageFor(m => m.LastName)
    </div>
}

しかし、よりクリーンなソリューションがあるべきだと感じています。Google は私を完全に失敗させました。要約するプロパティを表すコレクションを取るカスタム ヘルパーまたは検証要約拡張機能を見つけることができませんでした。

各セクションにはかなりの数のフィールドが含まれているため、ModelState.Keys の比較はすぐに見苦しくなります。これを行うためのきれいな方法はありますか?

4

1 に答える 1

4

しかし、よりクリーンなソリューションがあるべきだと感じています。

はい、カスタムの再利用可能な HTML ヘルパーを記述して、このタスクを達成できます。

public static class HtmlExtensions
{
    public static IHtmlString Summary<TModel>(
        this HtmlHelper<TModel> html, 
        params Expression<Func<TModel, object>>[] expressions
    )
    {
        var div = new TagBuilder("div");
        var sb = new StringBuilder();
        foreach (var expression in expressions)
        {
            var unary = expression.Body as UnaryExpression;
            if (unary != null && unary.NodeType == ExpressionType.Convert)
            {
                var lambda = Expression.Lambda(unary.Operand, expression.Parameters);                    
                sb.AppendLine(html.ValidationMessage(ExpressionHelper.GetExpressionText(lambda)).ToHtmlString());
            }
            else
            {
                sb.AppendLine(html.ValidationMessageFor(expression).ToHtmlString());
            }
        }
        div.InnerHtml = sb.ToString();
        return new HtmlString(div.ToString());
    }
}

そのように使用できます:

<h2>
    Your Info:
    @Html.Summary(
        x => x.FirstName,
        x => x.LastName
    )
</h2>

ヘルパーを使用すると、検証エラーとして要約に含めたいプロパティを一覧表示できます。

于 2013-03-29T15:52:45.410 に答える