Принуждение EditorFor для префикса входных элементов в представлении с именем класса?

У меня есть редактор для:

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

Это приведет к правильной привязке к представлению (как и ожидалось), но не приведет к привязке привязки, когда модель будет опубликована. Это связано с тем, что идентификатор формы не имеет префикса «Клиент».

Обычно в этой ситуации я просто передаю модель, а затем привязываю входные данные к model.Client.PropertyName в шаблоне, но в данном случае это не вариант, поскольку шаблон используется в двух разных моделях просмотра (у которых есть клиент).

Любые предложения по правильной привязке?

Большое спасибо, Кохан.


Дополнение

Похоже, это было недоразумением с моей стороны, проблема, как я теперь понимаю, в том, что fluentHtml не работает внутри EditorFor Templates. (То же самое касается этого исправления, которое, как оказалось, не понадобилось, поскольку EditorFor автоматически добавит префикс для меня, если я заменю fluentHtml обычными помощниками mvc html)


person 4imble    schedule 05.01.2011    source источник


Ответы (2)


Попробуйте что-нибудь вроде:

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

См. Ссылку, упомянутую Коханом в комментариях ниже.

person Julien Bérubé    schedule 05.01.2011
comment
Вы имеете в виду метод настраиваемого расширения, упомянутый в этом вопросе? stackoverflow.com/questions/2759167/ - person 4imble; 05.01.2011
comment
@Kohan: Точно, не знал, откуда взялся код! Спасибо! - person Julien Bérubé; 05.01.2011
comment
Также в вашем примере есть ошибка: ‹% using (Html.BeginHtmlFieldPrefixScope (Client)) {%› Html.EditorFor (model = ›model.Client, ClientTemplate, new {edit = false}); ‹%}%› Но все равно большое спасибо, надеюсь, я доберусь туда сейчас. - person 4imble; 05.01.2011
comment
Извините, кажется, все это было напрасно. EditorFor делает это автоматически, но это был fluentHtml в моем шаблоне, который все испортил. - person 4imble; 06.01.2011

Конфликт имен HTML в MVC3

Вырезание и вставка, которые не работают в 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>
}

Обратите внимание на использование, чтобы включить класс расширения в область видимости. Это позволяет работать второй строке использования.

Теперь проблема в том, что при обратной публикации объект не обновляется. В моем контроллере я использовал второй параметр, чтобы указать свой префикс:

TryUpdateModel(modelUser.Permission, "Permission");

Это добавило префикс ко всем полям в HTML, и TryUpdateModel загрузил объект с префиксными именами элементов управления. Теперь вы можете правильно использовать пространство имен для своих элементов управления для встроенных списков редактирования и для частичных видов моделей с одинаковыми именами свойств.

person Shawn Zernik    schedule 30.07.2011