Общий подход к отображению сообщения на любой странице

У меня есть довольно простое (для объяснения) требование для моего веб-приложения 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,

Другие вопросы по тегам