【问题标题】:Forcing EditorFor to prefix input items on view with Class Name?强制EditorFor在视图上使用类名作为输入项的前缀?
【发布时间】:2011-06-04 03:35:06
【问题描述】:

我有一个编辑器:

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

这将很好地绑定到视图(如预期的那样),但在模型发布时不会绑定回来。 这是因为表单 ID 没有以“客户”为前缀。

通常在这种情况下,我只是传入模型,然后将输入绑定到模板中的 model.Client.PropertyName 但在这种情况下这不是一个选项,因为模板用于两个不同的视图模型(有客户端) .

关于让它正确绑定的任何建议?

非常感谢, 可汗。


附录

这似乎是我的一个误解,我现在理解的问题是 fluentHtml 在 EditorFor 模板中不起作用。 (此修复也是如此,事实证明不需要,因为如果我用普通的 mvc html 帮助器替换 fluentHtml,EditorFor 会自动为我添加前缀)

【问题讨论】:

    标签: c# asp.net-mvc binding asp.net-mvc-3 editorfor


    【解决方案1】:

    尝试类似:

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

    您使用 EditorFor、LabelFor 等创建的每个字段都将带有前缀。

    编辑: 这是我正在使用的扩展方法,对不起!

    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;
        }
    }
    

    请参阅下面的 cmets 中 Kohan 提到的链接。

    【讨论】:

    • 您指的是这个问题中提到的自定义扩展方法吗? stackoverflow.com/questions/2759167/…
    • @Kohan:没错,不知道代码来自哪里!谢谢!
    • 您的示例中还有一个错误应该是: Html.EditorFor(model => model.Client, "ClientTemplate",新的 { 编辑 = 假 }); 不过还是非常感谢,我希望现在就到那里。
    • 对不起,看来这一切都是徒劳的。 EditorFor 会自动执行此操作,但我的模板中的 fluentHtml 搞砸了。
    【解决方案2】:

    MVC3 HTML 名称冲突

    在 MVC3 中不起作用的剪切和粘贴。为了让扩展工作,我必须创建一个类文件:

    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;
                }
            }
        }
    }
    

    在 Razor (.cshtml) 文件中,我添加了以下内容:

    @using incMvcSite.Classes
    @using(Html.BeginHtmlFieldPrefixScope("Permission")) {
        <fieldset>
            <legend>Permission</legend>
    
            // The Html.EditorFor's would go here...
        </fieldset>
    }
    

    注意使用将我的扩展类带入范围。这允许第二个 using 行工作。

    现在的问题是回发时,对象没有更新。在我的控制器中,我使用了第二个参数来指定我的前缀:

    TryUpdateModel(modelUser.Permission, "Permission");
    

    这为 HTML 中的所有字段添加了前缀,并且 TryUpdateModel 加载了带有前缀控件名称的对象。现在,您可以为嵌入式编辑列表和具有相同属性名称的模型的部分视图正确命名控件。

    【讨论】:

      猜你喜欢
      • 2015-04-09
      • 2010-12-02
      • 2016-02-18
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多