我对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
是首选方案,还是有“更好”的选择? (例如更强类型的东西)
答案 0 :(得分:2)
我的第一个想法是使用具有适当模型(带有字符串属性)的强类型视图。但是,这意味着要更改每个现有的非强类型视图以使用此模型,并更新所有现有模型以继承此新模型。
这是我能想象的唯一一致,可重复使用,可测试的解决方案,尽管可能会造成额外的工作。
答案 1 :(得分:1)
最佳做法是使用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在回答中的以下评论。这是我能想象的唯一一致,可重复使用,可测试的解决方案,尽管可能会造成额外的工作。
答案 2 :(得分:0)
您可以在项目中制定一个约定,即要显示的消息始终会进入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
。