У меня есть веб-сайт, на котором есть макет страницы. Однако на этой странице макета есть данные, которые все модели страниц должны предоставлять такой заголовок страницы, имя страницы и место, где мы на самом деле находимся для HTML-помощника, который я сделал, который выполняет некоторые действия. Также каждая страница имеет свои собственные свойства модели представления.
Как я могу это сделать? Кажется, что набирать макет - плохая идея, но как передать эту информацию?
asp.net-mvc-4
Rushino
источник
источник
ViewBag
. Возможно дело в предпочтениях. Проголосовали за ваш комментарийОтветы:
Если вам необходимо передать одни и те же свойства на каждую страницу, тогда будет разумным создать базовую модель представления, которая будет использоваться всеми вашими моделями представления. Тогда ваша страница макета может принять эту базовую модель.
Если за этими данными требуется логика, то ее следует поместить в базовый контроллер, который используется всеми вашими контроллерами.
Вы можете многое сделать, но важный подход - не повторять один и тот же код в нескольких местах.
Изменить: обновить из комментариев ниже
Вот простой пример, демонстрирующий концепцию.
Создайте базовую модель представления, от которой унаследуются все модели представления.
Ваша страница макета может принять это как образец.
Наконец, установите данные в методе действия.
источник
public class HomeController : BaseController
. Таким образом, общий код нужно написать только один раз, и его можно будет применить ко всем контроллерам.Я использовал HTML-помощник RenderAction для бритвы в макете.
Мне это было нужно для простой струны. Итак, мое действие возвращает строку и легко записывает ее. Но если вам нужны сложные данные, вы можете вернуть PartialViewResult и модель.
Вам просто нужно поместить вашу модель в начало частичного представления _maPartialView.cshtml, которое вы создали.
Затем вы можете использовать данные в модели в этом частичном представлении с помощью html.
источник
Другой вариант - создать отдельный класс LayoutModel со всеми свойствами, которые вам понадобятся в макете, а затем поместить экземпляр этого класса в ViewBag. Я использую метод Controller.OnActionExecuting для его заполнения. Затем в начале макета вы можете извлечь этот объект из ViewBag и продолжить доступ к этому строго типизированному объекту.
источник
OnActionExecuting
. Использование ViewBag также означает, что вы теряете безопасность типов в вашем контроллере, что никогда не бывает хорошо.Предположительно, основным вариантом использования этого является получение базовой модели для представления для всех (или большинства) действий контроллера.
Учитывая это, я использовал комбинацию нескольких из этих ответов, в первую очередь опираясь на ответ Колина Бэкона.
Верно, что это все еще логика контроллера, потому что мы заполняем модель представления, чтобы вернуться к представлению. Таким образом, правильное место для этого - в контроллере.
Мы хотим, чтобы это происходило на всех контроллерах, потому что мы используем это для страницы макета. Я использую его для частичных представлений, которые отображаются на странице макета.
Мы также по-прежнему хотим получить дополнительное преимущество от строго типизированной ViewModel.
Таким образом, я создал BaseViewModel и BaseController. Все контроллеры ViewModels наследуют от BaseViewModel и BaseController соответственно.
Код:
BaseController
Обратите внимание на использование OnActionExecuted, взятого из этого сообщения SO
HomeController
BaseViewModel
HomeViewModel
FooterModel
Layout.cshtml
_Nav.cshtml
Надеюсь, это поможет.
источник
Вам не нужно возиться с действиями или изменять модель, просто используйте базовый контроллер и приведите существующий контроллер из контекста представления макета.
Создайте базовый контроллер с желаемыми общими данными (заголовок / страница / местоположение и т. Д.) И инициализацией действия ...
Убедитесь, что каждый контроллер использует базовый контроллер ...
Отобразите существующий базовый контроллер из контекста представления на вашей
_Layout.cshml
странице ...Теперь вы можете ссылаться на значения в базовом контроллере со страницы макета.
ОБНОВИТЬ
Вы также можете создать расширение страницы, которое позволит вам использовать
this
.Тогда вам нужно только не забыть использовать
this.Controller()
контроллер, когда вы хотите.или конкретный контроллер, наследуемый от
_BaseController
...источник
если вы хотите передать всю модель, сделайте следующее в макете:
и добавьте это в контроллер:
источник
Я не думаю, что какой-либо из этих ответов достаточно гибок для большого приложения уровня предприятия. Я не фанат чрезмерного использования ViewBag, но в этом случае для гибкости я бы сделал исключение. Вот что бы я сделал ...
У вас должен быть базовый контроллер на всех ваших контроллерах. Добавьте свои данные макета OnActionExecuting в свой базовый контроллер (или OnActionExecuted, если вы хотите отложить это) ...
Затем в вашем _Layout.cshtml вытащите ViewModel из ViewBag ...
Или...
Это не влияет на кодирование контроллеров вашей страницы или моделей представлений.
источник
MyLayoutViewModel
динамически созданный, как я могу передать некоторые параметрыOnActionExecuting
методу?base.OnActionExecuting(filterContext)
вашOnActionExecuting
метод !!!Создание базового представления, представляющего модель представления макета, - ужасный подход. Представьте, что вам нужна модель, которая представляет навигацию, определенную в макете. Вы бы сделали
CustomersViewModel : LayoutNavigationViewModel
? Зачем? Почему вы должны передавать данные модели навигации через каждую модель представления, которая есть в вашем решении?Модель представления макета должна быть выделена сама по себе и не должна заставлять остальные модели представления зависеть от нее.
Вместо этого вы можете сделать это в своем
_Layout.cshtml
файле:Самое главное, нам это не нужно,
new LayoutViewModel()
и мы получим все зависимости, которыеLayoutViewModel
были разрешены за нас.например
источник
Scoped
объекта модели макета в ASP..Net Core.Другие ответы охватили почти все о том, как мы можем передать модель на нашу страницу макета. Но я нашел способ, с помощью которого вы можете динамически передавать переменные на страницу макета без использования какой-либо модели или частичного представления в макете. Допустим, у вас есть эта модель -
И вы хотите получить динамично развивающийся город и штат. Например,
в вашем index.cshtml вы можете поместить эти две переменные в ViewBag
А затем в вашем layout.cshtml вы можете получить доступ к этим переменным viewbag
источник
Есть другой способ справиться с этим. Возможно, это не самый чистый способ с архитектурной точки зрения, но он позволяет избежать боли, связанной с другими ответами. Просто вставьте службу в макет Razor, а затем вызовите метод, который получает необходимые данные:
Затем позже в виде макета:
Опять же, не чисто с точки зрения архитектуры (очевидно, что сервис не следует вводить непосредственно в представление), но он выполняет свою работу.
источник
@inject
мой взгляд, использование - лучшее решение.Вы также можете использовать RenderSection , он помогает вам вводить
Model
данные в_Layout
представление.Вы можете вводить
View Model
данные,Json
,Script
,CSS
, иHTML
т.д.В этом примере я вводю
Json
изIndex
представления вLayout
представление.Index.chtml
_Layout.cshtml
Это избавляет от необходимости создавать отдельную Базу
View Model
.Надежда кому-то помогает.
источник
то, что я сделал, очень просто и работает
Объявите свойство Static в любом контроллере, или вы можете создать класс данных со статическими значениями, если хотите, например:
Эти значения могут обновляться контроллерами в зависимости от операций. позже вы можете использовать их в своем _Layout
В _layout.cshtml
источник
Почему никто не предложил методы расширения для ViewData?
Опция 1
Мне кажется, что это наименее навязчивое и простое решение проблемы. Никаких жестко запрограммированных строк. Никаких наложенных ограничений. Никакого волшебного кодирования. Никакого сложного кода.
Установить данные на странице
Вариант # 2
Другой вариант, упрощающий объявление поля.
Установите данные на странице. Объявление проще, чем первый вариант, но синтаксис использования немного длиннее.
Вариант # 3
Затем можно объединить это с возвратом одного объекта, содержащего все поля, связанные с макетом, со значениями по умолчанию.
Установить данные на странице
У этого третьего варианта есть несколько преимуществ, и я считаю, что в большинстве случаев он является лучшим вариантом:
Простейшее объявление полей и значений по умолчанию.
Самый простой синтаксис использования при установке нескольких полей.
Позволяет устанавливать различные типы данных в ViewData (например, макет, заголовок, навигация).
Допускает дополнительный код и логику в классе LayoutData.
PS Не забудьте добавить пространство имен ViewDataExtensions в _ViewImports.cshtml
источник
Вы можете создать файл бритвы в папке App_Code, а затем получить к нему доступ со страниц просмотра.
Проект> Repository / IdentityRepository.cs
Проект> App_Code / IdentityRepositoryViewFunctions.cshtml:
Project> Views / Shared / _Layout.cshtml (или любой другой файл .cshtml)
источник
вместо этого вы всегда можете использовать другой подход, который также быстро
создайте новое частичное представление в общем каталоге и вызовите частичное представление в макете как
в вашем частичном представлении вы можете вызвать свой db и выполнить то, что вы хотите сделать
предполагая, что вы добавили свою базу данных Entity Framework
источник
Невероятно, что здесь никто этого не сказал. Передача модели просмотра через базовый контроллер - беспорядок. Мы используем утверждения пользователей для передачи информации на страницу макета (например, для отображения пользовательских данных на панели навигации). Есть еще одно преимущество. Данные хранятся в файлах cookie, поэтому нет необходимости извлекать данные в каждом запросе через частичные данные. Просто погуглите "утверждения идентичности asp net".
источник
Вы можете использовать это так:
источник