MvcHtmlString with Razor statements included

好久不见. 提交于 2019-12-13 18:27:28

问题


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>

回答1:


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.




回答2:


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");


来源:https://stackoverflow.com/questions/27046267/mvchtmlstring-with-razor-statements-included

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!