#asp.net-core-mvc #asp.net-core-3.1 #asp.net-mvc-viewmodel
#asp.net-core-mvc #asp.net-core-3.1 #asp.net-mvc-viewmodel
Вопрос:
Я новичок в ASP.NET Core и имеют некоторые проблемы с привязкой глобальных моделей и viewmodels к представлениям razor. Мое приложение представляет собой смесь веб-API и MVC с представлениями razor.
Моя цель
Когда я открываю ASP.NET На странице MVC мне нужно создать экземпляр модели, загрузив ее из базы данных ( DbContext
сервиса) на основе идентификатора, полученного в файле cookie. Я хочу использовать этот объект модели глобально в каждом представлении или частичном представлении.
Текущая реализация
Я могу получить доступ к файлам cookie в методах действий контроллеров страниц, так что мне нужно загружать модель из DbContext в каждом методе действия и привязывать ее как viewmodel к целевому представлению. Это непрактично, потому что я должен делать это в каждом контроллере страницы, потому что мне нужен этот объект модели на всех страницах в моей панели навигации.
Идея
Я думаю, что должна быть возможность доступа к файлам cookie и dbcontext в Startup.cs и привязать объект модели к _ViewStart.cshtml, чтобы он был доступен глобально в каждом представлении или частичном представлении. Даже этот подход был правильным, я понятия не имею, как будет выглядеть код. Потому что я изучаю веб-приложения с .NET Core, изучая на практике и пробуя и ошибаясь в данный момент. 🙁
Обновить
У меня есть страница макета _Layout.cshtml
, которая включает частичные представления, такие как _NavPane.cshtml
. Моя цель — передать объект модели в _Layout, экземпляр которого создается путем загрузки из базы данных (у меня есть сервис IMandantRepository
для этой цели) и зависит от файла cookie.
Этот объект модели необходим при каждом запросе страницы. Вот почему было бы лучше загружать объект модели вне контроллеров страниц MVC и передавать его им (что я не могу реализовать технически).
Я попытался найти решение самостоятельно и в итоге получил следующее промежуточное уродливое решение. Ниже приводится содержимое _ViewStart
файла. Внизу я назначаю необходимые глобальные переменные, которые я могу использовать в каждом представлении или частичном представлении.
Это решение имеет как минимум два недостатка:
- Возможно, объект модели загружен избыточно.
- Слишком много программной логики в файле представления.
@inject MyProject.Data.IMandantRepository mandantRepo
@{
// Main layout template
Layout = "_Layout";
// Define default values
bool showAdminSection = false;
string src = "/images/logos/nologo.png";
// Read cookie value
string currentMandantUid;
Context.Request.Cookies.TryGetValue("currentMandant", out currentMandantUid);
// Load mandant from the database
var thisMandant = mandantRepo.GetMandantByUid(currentMandantUid);
if(thisMandant is Mandant){
src = "data:image/*;base64," thisMandant.GetBase64Logo();
showAdminSection = thisMandant.Abbr == "AdminMandant";
}
// Assing global variables to ViewData
ViewData["CurrentMandant"] = thisMandant;
ViewData["logoSrc"] = src;
ViewData["showAdminSection"] = showAdminSection;
}
Комментарии:
1.
I need that model object on all pages in my navigation page
Вы пытались поместить навигацию на страницу макета? Если вы хотите создать навигацию на основе данных, хранящихся в БД, вы можете реализовать и использовать пользовательский сервис для запроса данных, затем вы можете вызвать эту службу в layout и предоставить данные для меню навигации.2. @FeiHan Спасибо за ваш ответ. Я обновил свой вопрос небольшим объяснением о макете представления и моем промежуточном решении. Идеальным решением для меня было бы загрузить объект модели вне контроллеров страниц MVC и передать его в контроллер страницы и представление макета или использовать его глобально.
Ответ №1:
Это пример кода в ConfigureService() of Startup.cs
. Вы можете зарегистрировать свой dbContext
класс таким образом.
services.AddDbContext<BookStoreContext>( options =>
options.UseSqlServer(_configuration.GetConnectionString("DefaultConnection")));
Комментарии:
1. Спасибо за ваш ответ. Я обновил свой вопрос промежуточным решением, что не является лучшей практикой. Я думаю, лучшим решением может быть следующее с помощью метода Confiure() в Startup.cs string mycookie = app. Службы приложений. GetService<HttpContextAccessor>().HttpContext.Request. Cookies[‘MyCookie’]; var MyModel = приложение. Службы приложений. GetService<IMandantRepository>().GetMandantByAbbr(mycookie); // Как внедрить MyModel в _Layout.cshtml или получить к нему доступ из _Layout.csthml???
2. Забудьте идею о добавлении кода в Startup.cs в моем последнем комментарии. Это ошибка новичка. Методы запуска выполняются только один раз, при запуске хоста веб-приложения. 🙂 Я считаю, что мне нужно промежуточное программное обеспечение, которое считывает cookie и устанавливает объект глобальной модели. Но открытый вопрос заключается в том, как передать глобальный объект в _Layout.cshtml…