MvcHtmlString with Razor statements included

2019-08-10 02:40发布

I find myself repeating this code block too often...

        <div class="form-group">
            <div class="col-sm-3 control-label">
                @Html.LabelFor(m => m.Name)
            </div>
            <div class="col-sm-9">
                @Html.TextBoxFor(m => m.Name, null, new { @class = "form-control" })
                @Html.ValidationMessageFor(m => m.Name)
            </div>
        </div>

I have been attempting to create a MvcHtmlString custom extension, but it assumes that the @Html.LabelFor commands are text and that is what is displayed.

EDIT: Thanks Joe and Stephen!! That's what I was missing.

Here's the final answer for my code block

    static MvcHtmlString BaseFieldFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, string>> expression, MvcHtmlString innerHtml, string style = null) {

        var labelDiv = new TagBuilder("div");

        labelDiv.AddCssClass("col-sm-3 control-label");
        labelDiv.InnerHtml += helper.LabelFor(expression, new {
            htmlAttributes = new { @class = "form-control" }
        });

        var textDiv = new TagBuilder("div");

        textDiv.AddCssClass("col-md-9");
        textDiv.InnerHtml += innerHtml;
        textDiv.InnerHtml += helper.ValidationMessageFor(expression);

        var groupDiv = new TagBuilder("div");

        groupDiv.AddCssClass("form-group");
        groupDiv.InnerHtml += labelDiv;
        groupDiv.InnerHtml += textDiv;

        return new MvcHtmlString(groupDiv.ToString(TagRenderMode.Normal));
    }

and for usage

    public static MvcHtmlString FieldFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, string>> expression, string style = null) {

        var innerHtml = helper.TextBoxFor(expression, null, new { @class = "form-control", style });

        return BaseFieldFor(helper, expression, innerHtml, style);
    }

    public static MvcHtmlString DropDownListFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, string>> expression, IEnumerable<SelectListItem> list, string style = null){

        var innerHtml = helper.DropDownListFor(expression, new SelectList(list, "Value", "Text"), new { @class = "form-control", style });

        return BaseFieldFor(helper, expression, innerHtml, style);
    }

And now I can use it simply!

    <div class="panel-body form-horizontal">
        @Html.FieldFor(m => m.Name)
        @Html.FieldFor(m => m.Address1)
        @Html.FieldFor(m => m.Address2)
        @Html.FieldFor(m => m.City)
        @Html.DropDownListFor(m => m.State, AllowableValues.StateList, "max-width: 200px;")
        @Html.FieldFor(m => m.PostalCode, "max-width: 150px;")
        @Html.FieldFor(m => m.Phone, "max-width: 150px;")
    </div>

2条回答
The star\"
2楼-- · 2019-08-10 03:04

Your helper needs to use the inbuilt helper methods for generating your html. For example

MvcHtmlString label = LabelExtensions.LabelFor(helper, expression});

Refer this example for creating a helper that outputs similar html including the label, textbox and validation message.

查看更多
We Are One
3楼-- · 2019-08-10 03:24

You're not able to invoke the HTML helpers in the manner that you're trying to do so. All it will do is treat it as text out output the result as you've already seen.

Instead you need to reference the HTML helper along the lines of this:

string yourString = "Your string " + helper.LabelFor("text", "actionName");
查看更多
登录 后发表回答