Forcing EditorFor to prefix input items on view with Class Name?

烈酒焚心 提交于 2019-12-01 05:59:22

Try something like:

<% Html.BeginHtmlFieldPrefixScope("Client") {
  Html.EditorFor(model => model.Client, "ClientTemplate", new { editing = false });
<% } %>

Every field you make with EditorFor, LabelFor and the likes will be prefixed.

EDIT: Here's the extension method I'm using, sorry!

public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
  return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}

...and the class...

private class HtmlFieldPrefixScope : IDisposable
{
    private readonly TemplateInfo templateInfo;
    private readonly string previousHtmlFieldPrefix;

    public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
    {
        this.templateInfo = templateInfo;

        previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
        templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
    }

    public void Dispose()
    {
        templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
    }
}

See the link mentioned by Kohan in the comments below.

Shawn Zernik

MVC3 HTML Name Clashing

Cutting and pasting that does not work in MVC3. To get the extension to work, I had to create a class file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace incMvcSite.Classes {
    public static class HtmlPrefixScopeExtensions {
        public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix) {
            return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
        }

        private class HtmlFieldPrefixScope : IDisposable {
            private readonly TemplateInfo templateInfo;
            private readonly string previousHtmlFieldPrefix;

            public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix) {
                this.templateInfo = templateInfo;

                previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
                templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
            }

            public void Dispose() {
                templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
            }
        }
    }
}

In the Razor (.cshtml) file, I added the following:

@using incMvcSite.Classes
@using(Html.BeginHtmlFieldPrefixScope("Permission")) {
    <fieldset>
        <legend>Permission</legend>

        // The Html.EditorFor's would go here...
    </fieldset>
}

Notice the using to bring me extension class into scope. That allows the second using line to work.

Now the problem is that when posting back, the object is not updated. In my controller, I used a second parameter to specify my prefix:

TryUpdateModel(modelUser.Permission, "Permission");

This added the prefix to all field in the HTML, and the TryUpdateModel loaded the object with prefixed control names. Now you can properly namespace your controls for embedded edit lists, and for partial views of models with the same property names.

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