Общий подход к отображению сообщения на любой странице
У меня есть довольно простое (для объяснения) требование для моего веб-приложения ASP.NET MVC:
На любой странице можно отобразить сообщение на основе события, произошедшего на предыдущей странице. Сообщения могут включать в себя динамический контент, такой как информация, введенная пользователем при отправке формы.
Похоже на это...
Подход должен работать в сценариях POST-REDIRECT-GET.
Если у пользователя есть две вкладки браузера (которые совместно используют состояние сеанса), открытые в приложении, то любое сообщение должно отображаться только на вкладке, в которой произошло соответствующее событие.
Например:
После отправки формы обратной связи, сообщение с благодарностью пользователя (по имени)
При входе в систему появляется сообщение о дате и времени последнего входа пользователя в приложение.
Моей первой мыслью было использование строго типизированного представления с соответствующей моделью (с string
собственность) для этого. Однако это будет означать изменение каждого существующего представления без строгой типизации для использования этой модели и обновление всех существующих моделей для наследования от этой новой модели.
Это похоже на излишество.
Альтернативой является сохранение сообщения в TempData
:
// In my controller
TempData["Message"] = "Some kind of message";
// In my shared master view
@if (TempData["Message"] != null)
{
<div class="message">@TempData["Message"]</div>
}
С помощью TempData
более подробно рассматривается в этом посте. Интересно, что автор также предлагает использовать собственный HTTP-заголовок в качестве альтернативы. Интересная идея, но не работает с POST-REDIRECT-GET.
Использует TempData
предпочтительный вариант или есть "лучшая" альтернатива? (например, что-то более строго набранное)
3 ответа
Моей первой мыслью было использовать строго типизированное представление с подходящей моделью (со строковым свойством) для этого. Однако это будет означать изменение каждого существующего представления без строгой типизации для использования этой модели и обновление всех существующих моделей для наследования от этой новой модели.
Это единственное последовательное, многоразовое, тестируемое решение для этого, которое я могу себе представить, несмотря на дополнительную работу, которую это может вызвать.
Лучше всего использовать ViewModels
общаться между View
а также Controllers
, Вы можете иметь базу View Model
и все остальное View Models derived from that
как показано ниже:
public class BaseVM
{
public string Message{ get; set;}
}
public class CreateViewModel: BaseVM
{
public string CustoomerName{ get; set;}
}
Вы можете заполнить Message
свойство при возврате модели в контроллер, как показано ниже:
public ActionResult Step2()
{
//Some Logic
step2Model.Message = "Yes, Success..!!";
return View(step2Model);
}
После этого на каждой странице просмотра вы можете проверить, есть ли в этом свойстве что-либо. Вы можете сделать это, как показано ниже:
@if(!string.IsNullOrEmpty(Model.Message))
{
//Show message
}
РЕДАКТИРОВАТЬ:
OP хорошо знает об этом подходе, но все еще сохраняет этот ответ, поскольку у него есть фрагмент, чтобы показать, как сделать это в коде. Во-вторых, когда дело доходит до использования ViewModels, я согласен с последующим комментарием CodeCaster в своем ответе.
Это единственное последовательное, многоразовое, тестируемое решение для этого, которое я могу себе представить, несмотря на дополнительную работу, которую это может вызвать.
Вы можете заключить соглашение в своем проекте, что сообщение для отображения всегда будет ViewBag.InfoMessage
динамическая переменная. Итак, в вашем файле макета вы бы отобразили его, если он будет передан в представление из контроллера.
Более строгим способом было бы создать класс базовой модели с InfoMessage
свойство и получить все другие модели / модели представления из этой базы.
Чтобы сохранить сообщение в сценарии POST-REDIRECT-GET, используйте переменную сеанса, которая будет очищена после отправки значения в представление - чтобы избежать отображения на нескольких страницах.
Вот некоторый код:
public class BaseViewModel
{
public string InfoMessage { get; set; }
}
public class SpecificViewModel : BaseViewModel
{
// other model properties
}
В вашем контроллере тогда:
SpecificViewModel vm = new SpecificViewModel();
vm.InfoMessage = Session["InfoMessage"] as string;
Session["InfoMessage"] = null;
// other code
return View(vm);
Конечно, ваш взгляд будет иметь строго типизированную модель: SpecificViewModel
,