【问题标题】:General approach for displaying a message on any page在任何页面上显示消息的一般方法
【发布时间】:2013-06-11 13:56:37
【问题描述】:

我的 ASP.NET MVC Web 应用程序有一个相当简单(解释)的要求:

在任何页面上,都能够根据前一页面上发生的事件显示消息。消息可能包含动态内容,例如用户在表单提交中输入的信息。

类似的...

该方法必须适用于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>
}

this blog posting 中更详细地介绍了使用 TempData。有趣的是,作者还建议使用自定义 HTTP 标头作为替代方案。一个有趣的想法,但是does not work with POST-REDIRECT-GET

使用TempData 是首选选项,还是有“更好”的选择? (例如,更强的类型)

【问题讨论】:

    标签: c# asp.net-mvc-4


    【解决方案1】:

    我的第一个想法是为此使用具有适当模型(带有字符串属性)的强类型视图。然而,这意味着更改每个现有的非强类型视图以使用此模型,并更新所有现有模型以继承此新模型。

    这是我能想象到的唯一一致、可重复使用、可测试的解决方案,尽管它可能会导致额外的工作。

    【讨论】:

    【解决方案2】:

    最佳做法是使用ViewModelsViewControllers 之间进行通信。你可以有一个基础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 很清楚这种方法,但仍然保留这个答案,因为它有一个 sn-p 来显示如何在代码中执行此操作。其次,在使用 ViewModels 时,我同意 CodeCaster 在他的回答中的以下评论。

    这是我能想象到的唯一一致、可重复使用、可测试的解决方案,尽管它可能会导致额外的工作。

    【讨论】:

      【解决方案3】:

      您可以在项目中约定要显示的消息将始终进入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

      【讨论】:

      • 一个代码示例会很棒。我只是在 POST-REDIRECT-GET 场景中尝试过这个,ViewBag 数据在重定向之后没有持续存在。
      • 对不起,我有点错过了您问题中对 POST-REDIRECT-GET 的要求。为此,您最好使用会话变量在页面之间保留消息。然后,您将以所描述的方式使用该值:在 ViewBag 或基本模型类中。我会发布一些代码并更新答案。
      猜你喜欢
      • 2018-03-15
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2013-02-04
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多