#c# #asp.net-mvc #performance #caching #model
#c# #asp.net-mvc #Производительность #кэширование #Модель
Вопрос:
Хорошо, поэтому я постараюсь сделать вещи короткими и понятными.
Как вы, возможно, знаете, у меня есть моя база данных, использующая EntityFramework, затем у меня есть классы модели базы данных, которые инициализируются базой данных, а затем у меня есть модели представления, в которых у меня есть поля для каждого элемента управления html, в последнем у меня есть контроллер с определенным экземпляром ViewModel.
Мой вопрос в том, что модель представления создается один раз по запросу моего контроллера (любое действие), в других случаях я всегда проверяю, равно ли оно нулю, и если оно равно нулю, тогда я перестраиваю модель представления, извлекая данные из базы данных, используя мои классы моделей базы данных, это правильноправильно? Таким образом, я могу добиться улучшения производительности.. верно? поскольку я повторно использую модель представления и не создаю ее каждый раз …?
Проблема возникает, когда какое-либо поле обновляется администратором в бэк-офисе. Как я могу это преодолеть? Я вижу следующие варианты:
1) Установите время жизни (минуты / часы) для моего объекта ViewModel внутри контроллера (по истечении срока действия я устанавливаю для него значение null).
2) Я пытаюсь обработать CTRLF5комбинацию клавиш и устанавливаю для объекта ViewModel внутри контроллера значение null.
3) Я перестраиваю ViewModel при каждом http-запросе к контроллеру (это так плохо …)
4) Я использую Http-сеанс каждого клиента, когда серверная часть обновляет поле, каждый Http-сеанс на моем ASP.NET WebApplication get запускается с некоторым флагом, чтобы установить для объекта модели представления значение null (я даже не знаю, возможно ли это, но это кажется самым элегантным способом, не так ли?
Вот пример того, что я делаю в данный момент, но в некоторых случаях мне может потребоваться воссоздать ViewModel (поскольку база данных для полей представления изменилась):
[Authorize]
public class HomeController : Controller
{
private IndexViewModel indexModel;
[Authorize]
public ActionResult Index(IndexViewModel model, string lang = "en")
{
indexModel = model;
if (indexModel == null)
indexModel = new IndexViewModel();
indexModel.SelectedLanguage = lang;
return View(indexModel);
}
//more actions..
}
С нетерпением ждем всех ваших ответов и отзывов,
Этот вопрос в первую очередь направлен на оптимизацию производительности и процессорного времени, я хочу, чтобы у моих клиентов был свежий, чистый и быстрый опыт использования моего веб-сайта.
Спасибо!
РЕДАКТИРОВАТЬ: вопрос отредактирован с дополнительной информацией.
Комментарии:
1. Что вы имеете в виду в других случаях, когда я всегда проверяю, равно ли оно нулю ? Сохраняете ли вы модель представления в
Session
(и почему?). И что заставляет вас думать, что инициализация вашей модели представления при каждом запросе плоха?2. Привет @StephenMuecke спасибо за ваш ответ. Я имею в виду, что я делаю что-то вроде проверки того, что модель равна нулю, в этом случае я снова создаю модель, вы понимаете? Я все равно не сохраняю модель, модель просто продолжает переходить от представления контроллера к view-controller, я получаю модель в параметрах моего метода действия. Я говорю, что инициализация моей модели представления плоха, потому что я буду использовать процессор в тех случаях, когда данные вообще не изменились… поэтому я мог бы использовать те же поля, которые уже существуют в объекте представления модели…
3. Я понимаю, что вы пытаетесь поддерживать свою модель представления в актуальном состоянии, но вы не хотите запрашивать базу данных при каждом http-запросе, поступающем на контроллер. Это то, что вы имеете в виду?
4. @DarkLink, я бы так не поступил. Если вы хотите сохранить состояние вашей модели представления между запросами к вашему контроллеру, вам лучше сохранить его в
Cache
объекте и настроить для него политику истечения срока действия. Затем вы можете просто проверить, доступен ли объект в кэше, и, если нет, инициализировать его и обновить из базы данных.5. Вам нужно будет включить значения всех свойств вашей модели в URL. Но это действительно не имеет смысла, и неясно, что вы пытаетесь сделать с этим кодом. Веб не имеет состояния. Когда вы делаете запрос, создается новый экземпляр вашего контроллера, и значение
indexModel
всегда будетnull
. Если вы не передали значения своей модели в URL, тоmodel
это просто новый экземплярIndexViewModel
. ТАКИМ образом, вы можете удалить 1-ю строку кода 3 и просто использоватьmodel.SelectedLanguage = lang; return View(model);
Ответ №1:
По умолчанию ASP.NET Контроллеры MVC создаются при каждом запросе. Это означает, что ваша indexModel
переменная всегда будет null
отображаться в каждом запросе. Веб не имеет состояния, поэтому у вас мало вариантов для хранения информации между запросами.
На стороне клиента
- Cookie
- Скрытые поля
На стороне сервера
- База данных или другое хранилище
- Сессия
- Кэш
Насколько я понял, вы используете некоторую базу данных и просто хотите предотвратить отправку запросов в базу данных при каждом запросе для достижения лучшей производительности. Одним из вариантов является использование System.Web.Caching.Cache
object . Затем вы можете написать что-то подобное.
public class HomeController : Controller
{
[Authorize]
public ActionResult Index(string lang = "en")
{
IndexViewModel indexViewModel;
if (HttpContext.Cache["IndexViewModel"]!=null)
{
indexViewModel = HttpContext.Cache["IndexViewModel"];
}
else
{
// get your index view model from database by calling some service or repository
indexViewModel = DatabaseService.GetIndexViewModelFromDatabase();
// once we got the view model from a database we store it to cache and set it up so that it gets expired in 1 minute
HttpContext.Cache.Insert("IndexViewModel", indexViewModel, null, DateTime.UtcNow.AddMinutes(1), Cache.NoSlidingExpiration);
}
indexViewModel.SelectedLanguage = lang;
return View(indexModel);
}
[HttpPost]
[Authorize(Roles="Backoffice")]
public ActionResult ResetCache(string cacheKey)
{
if (HttpContext.Cache[cacheKey] != null)
HttpContext.Cache.Remove(cacheKey);
}
//more actions..
}
Комментарии:
1. Спасибо за ваш вклад, Алексей! Я искал это, это действительно помогает мне, не могли бы вы просто сказать мне одну вещь? и, может быть, отредактируйте свой ответ своим ответом об этом? Вопрос в следующем: «Может ли сервер, я имею в виду, пользователь с определенной ролью (backoffice) вызвать определенное действие в контроллере, которое запускает установку всего кэша клиента в значение null? Итак, мне не нужно ждать истечения срока действия, и данные немедленно обновляются после следующей проверки объекта модели? Спасибо!
2. Да, это верно, я знаю, что это способ сделать это, мой вопрос в том, удалит ли это кэш для зарегистрированного пользователя, верно? не все просматривают веб-сайт, используя кеш в этот момент, верно? Возможно, это слишком глупо спрашивать и даже невозможно… но чтобы вы поняли, я хотел бы запустить эту операцию (resetcache) для всех, кто просматривает в этот конкретный момент…
3. @DarkLink, согласно документации
Cache
, для каждого домена приложения создается один экземпляр. Это означает, что это общее для всех ваших пользователей, поэтому, если вы поместите или удалите что-то в / из кэша, это повлияет на всех ваших пользователей. Если ваша viewmodel должна содержать некоторую пользовательскую информацию, вы можете изменить ключ «IndexViewModel», скажем, на «IndexViewModel_xx», где xx — уникальный идентификатор или адрес электронной почты текущего вошедшего в систему пользователя. Это позволит сбросить кэш или настроить его для каждого пользователя индивидуально.4. Большое вам спасибо @AlexeyAndrushkevich! Это именно то, что я ищу! 🙂