Как заполнить строго типизированные данные представления из базового контроллера?

Все мои контроллеры основаны на BaseController, чтобы обмениваться свойствами между ними и переопределять OnActionExecuting для установки некоторых значений на основе маршрута.

Я создаю класс BaseViewData, чтобы сделать то же самое для всех данных моего представления.

На данный момент я заполняю данные представления следующим образом (C #):

var viewData = new BaseViewData
{
    Name = "someName",
    Language = "aLanguage",
    Category = "aCategoryName"
};

Я делаю это при каждом действии, требующем данных представления. Некоторые свойства являются общими, их нужно устанавливать для каждого действия. Есть ли способ установить некоторые свойства в более глобальном масштабе?

Если я создаю экземпляр класса BaseViewData в методе OnActionExecuting в BaseController, как мне получить доступ к свойствам BaseViewData из действия в обычных контроллерах (производных от BaseController)?

Обновление в ответ на Денниса Палмера:

По сути, я делаю это из-за того, что у меня проблема с ViewData ["lang"], которая не заполняется случайным образом по некоторым запросам. ViewData ["lang"] содержит "en", если язык английский, и "ja", если он японский (ну, в любом случае так и должно быть). Я заполняю ViewData ["lang"] внутри OnActionExecuting на BaseController.

На мой взгляд, я обращаюсь к некоторым частичным представлениям на основе языка:

<% Html.RenderPartial(ViewData["lang"] + "/SiteMenu"); %>

Но я случайно получаю сообщения об ошибках с состоянием «Cannot find / SiteMenu», что указывает на то, что ViewData [«lang»] не имеет значения. Я просто не могу найти причину, по которой ViewData ["lang"] не заполняется. Итак, я переписываю сайт, чтобы использовать ТОЛЬКО строго типизированные данные представления (и устанавливаю некоторые жесткие значения по умолчанию). Но если другой способ лучше, я пойду по нему.

Спасибо!


person Chaddeus    schedule 17.12.2009    source источник


Ответы (2)


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

Есть ли в ваших маршрутах имя, язык и категория? Если это так, то HtmlHelper будет иметь доступ к информации о маршруте и сможет определять, что отображать, с помощью методов расширения. Какова взаимосвязь между вашими маршрутами и тем, что нужно знать вашим взглядам?

Обновление: lang является частью вашего маршрута? Если это так, то я бы по-прежнему утверждал, что вы могли бы написать метод расширения HtmlHelper, который просматривает данные маршрута напрямую и определяет, какой частичный вид нужно визуализировать. Таким образом, вашему контроллеру даже не нужно будет беспокоиться об установке ViewData ["lang"]. Представление всегда будет знать, как выполнить рендеринг на основе маршрута.

Обновление 2: я думаю, что отказ от использования метода расширения HtmlHelper, поскольку он повторно оценивает данные маршрута, может быть случаем преждевременной оптимизации. Ваша схема наследования контроллера кажется слишком сложной, и вы задали вопрос, потому что способ, которым вы устанавливали ViewData, был ненадежным. Я сомневаюсь, что извлечение значения из данных маршрута было бы гораздо менее эффективным, если оно вообще было бы, менее эффективным, чем установка и чтение из ViewData.

Из вашего комментария:

В контроллере я использую значение lang, чтобы также определить, какое представление отображать.

Это только наводит меня на мысль, что есть еще несколько частей вашей системы, которые мне нужно увидеть, чтобы дать лучший совет. Если у вас есть отдельные представления для каждого языка, то почему в представлении нужно указывать, какой язык использовать?

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

person CoderDennis    schedule 17.12.2009
comment
Да, язык - это часть моего пути. В контроллере я использую значение lang, чтобы также определить, какое представление отображать. Например, www.apoads.com/en/Yokota. Маршрут выглядит так: {language} / {b} (b - сокращение от base, в данном случае военная база - не имеет отношения к программированию). - person Chaddeus; 17.12.2009
comment
Я создал помощник html, чтобы получить данные маршрута и вернуть язык на основе токена маршрута. Моя главная страница содержит много ссылок на это значение ... использование расширения HtmlHelper означает, что он выполняет работу по получению этого значения каждый раз, когда на него ссылаются, верно? Это одна из причин, по которой я устанавливал его на контроллере, выполнял работу один раз и ссылался на это значение несколько раз. Или я ошибаюсь? - person Chaddeus; 17.12.2009
comment
Всем очень хороший совет. В моем случае есть одна главная страница, которая использует несколько различных частичных представлений в зависимости от языка. Да, внутри других представлений язык жестко запрограммирован. Сейчас я создаю класс BaseViewData, делаю его свойством BaseController и создаю его экземпляр с en, установленным на языке по умолчанию. Поскольку КАЖДОМУ представлению потребуется доступ к нескольким ключевым частям данных, я пошел по этому пути. У меня до сих пор написан HtmlHelper, который вы предложили, на случай, если он когда-нибудь пригодится. Благодарю вас за ответы. - person Chaddeus; 18.12.2009

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

person Frank Krueger    schedule 17.12.2009
comment
Хм ... возможно. Спасибо за ссылку - я впервые ее увидел и всегда хотел подробнее изучить фильтры действий. - person Chaddeus; 17.12.2009