Вставить выбранный путь просмотра в качестве HTML-комментария в начало и конец вывода действия - PullRequest
2 голосов
/ 21 декабря 2010

В настоящее время я создаю многопользовательское веб-приложение с использованием MVC 3. По крайней мере 30 различных веб-сайтов будут иметь общую кодовую базу, и, хотя они также имеют аналогичные встроенные функции, они должны выглядеть значительно по-разному.,Вследствие этого я использую URL-адрес для внутреннего разделения клиентов и переопределенный механизм представления Razor (по крайней мере, с точки зрения поиска представления) для автоматического выбора либо настраиваемого представления для данного действия, либо представления по умолчанию.

Чтобы помочь «разделить» сложную страницу, любое конкретное представление будет использовать несколько частичных элементов, обычно представляемых как автономные действия, так что обычно пользовательское представление или частичное представление будет иметь только небольшие различия HTML, помогая минимизироватьлюбой код, специфичный для сайта клиента.

Надеюсь, вы следили за этим фоном!

Таким образом, одна HTML-страница может состоять из множества небольших фрагментов частичных представлений HTML, которые могут быть получены из конкретныхпапки для клиента или универсальная версия.Я надеюсь, что нашему дизайнеру будет легче внести незначительные изменения в страницу, легко увидев , где в структуре папок, бит HTML, который он хочет изменить.

Мое предложението, что каждый частичный будет заключен в скобки с комментариями HTML, такими как:

{Содержимое частичного}

Очевидно, что я мог бы вставить их вручную, но это просто напрашивается на проблемы, для опечаток, для скопированных и затем измененных версий клиента, которые не обновляются с правильным URL.Я думаю, должно быть возможно извлечь это из некоторого контекста и внедрить его.

В то же время мне нужно иметь возможность не делать этого для определенных действий.Например, частичная может генерировать текст внутри, скажем, текстовой области, поэтому комментарии там не будут подходящими.В целом, я рад поместить эти комментарии в , если только я не укажу, что это не подходит.

Для меня это предполагает ActionFilter для Action, который я могу применить ко всему сайту, а затемотключить для определенных действий.Я надеюсь, что одно из переопределяемых событий позволило бы мне определить этот путь, но я не могу найти, где он хранится.Кроме того, OnResultExecuting, похоже, срабатывает до того, как будет выбран Partial, а OnResultExecuted, похоже, уже выписал содержимое Partial, поэтому я не могу вставить начальный комментарий здесь.Я также не могу найти ссылку на путь к выбранному фрагменту.

Просто для полноты, я намерен, чтобы этот атрибут записывал эти комментарии только при компиляции в режиме отладки.

ИтакКто-нибудь знает, как я мог бы получить путь к выбранному представлению без какого-либо взлома между FindPartialView и атрибутом?Является ли мой метод атрибутов лучшим выбором или есть более простой способ сделать это?Возможно, что-то уже встроено!

Большое спасибо за вашу помощь.

1 Ответ

0 голосов
/ 23 сентября 2011

Ну, я никогда не забывал о желании этого и всегда надеялся, что однажды решу это, и, к счастью, у меня есть.

Я переопределил WebViewPage по умолчанию (я использую движок Razor) и, в частности, ExecutePageHierarchy для добавления комментариев:

public abstract class PaladinWebViewPage : PaladinWebViewPage<dynamic>
{
}

public abstract class PaladinWebViewPage<TModel> : WebViewPage<TModel>
{
    public bool DisplaySourceCodeComments
    {
        get { return ((bool?) ViewBag.__DisplaySourceCodeComments) ?? false; }
        set { ViewBag.__DisplaySourceCodeComments = value; }
    }

    public override void ExecutePageHierarchy()
    {
        base.ExecutePageHierarchy();

        // Filters can be used to set and clear this value so we can decide when to show this comment
        if (!DisplaySourceCodeComments) return;

        var sw = Output as StringWriter;
        if (sw == null) return;

        var sb = sw.GetStringBuilder();
        sb.Insert(0, string.Format("<!-- Start of {0} -->", VirtualPath));
        sb.AppendFormat("<!-- End of {0} -->", VirtualPath);
    }

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

Также, чтобы использовать эту страницу просмотра, вам нужно отредактировать Views / Web.config и изменить pageBaseType на этот тип.

Я хочу выборочно включать и выключать эти комментарии, поэтому я создал ActionFilter:

public class DisplaySourceCodeCommentsAttribute : ActionFilterAttribute
{
    private readonly bool _displaceSourceCodeComments;

    public DisplaySourceCodeCommentsAttribute(bool displaceSourceCodeComments)
    {
        _displaceSourceCodeComments = displaceSourceCodeComments;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);

        var viewResult = filterContext.Result as ViewResultBase;
        if (viewResult == null) return;

        viewResult.ViewBag.__DisplaySourceCodeComments = _displaceSourceCodeComments;
    }
}

Я немного недоволен тем, что мне пришлось использовать ViewBag здесь, а также отдельно в переопределении страницы представления, так как они не тесно связаны, но я не могу найти способ прямого взаимодействия фильтра с страница просмотра, так что это что-то вроде выдумки. Преимущество состоит в том, что отображение исходного кода для представления или части также автоматически отображает его для любых дочерних частичек, пока вы не отключите его снова, поскольку ViewBag передается по цепочке.

При этом любое действие может включить комментарии исходного кода с помощью [DisplaySourceCodeComments (true)]

или, очевидно, выключите его снова с false

Атрибут проверяет, что результатом контекста является ViewResultBase, что означает только Views и Partials, поэтому Json, Content или перенаправления не затрагиваются, что тоже очень удобно.

Наконец, я делаю этот фильтр действия глобальным при работе в режиме отладки, чтобы в каждое представление и частичное включался исходный комментарий, добавив следующую строку в global.asax.cs:

[#] если DEBUG

        // When in debug mode include HTML comments showing where a view or partial has come from
        GlobalFilters.Filters.Add(new DisplaySourceCodeCommentsAttribute(true));

[#] ENDIF

Я действительно счастлив, что наконец-то сортировал его, поэтому надеюсь, что это будет полезно для кого-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...