简化示例:
[HttpGet]
public ActionResult Report(DateTime? date)
{
if (!date.HasValue)
{
date = DateTime.Now;
}
// Clear the ModelState so that the date is displayed in the correct format as specified by the DisplayFormat attribute on the model
ModelState.Clear();
// Expensive call to database to retrieve the report data
ReportModel model = DataAdapter.Convert(this.reportService.GetReport((DateTime)date));
// Store in TempData in case validation fails on HttpPost
TempData["ReportModel"] = model;
return View(model);
}
[HttpPost]
public ActionResult Report(ReportModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Report", new { date = model.Date });
}
else
{
// Load the report from TempData, and restore again in case of another validation failure
model = TempData["ReportModel"] as ReportModel;
TempData["ReportModel"] = model;
// Redisplay the view, the user inputted value for date will be loaded from ModelState
return View(model);
}
}
我的问题是,我是否以正确的方式将报告数据存储在TempData中?代码看起来有点奇怪,特别是在HttpPost操作方法中读取然后写回TempData,以确保它持久保存下一个请求。
我能想到的其他选择是:
(1)从HttpPost操作再次调用服务层(我不想再进行另一次数据库调用,因为验证失败只是为了重新显示表单,因为它似乎效率低下)。我想我可以在服务层实现缓存,以避免数据库往返...
(2)在表格中使用隐藏的输入(yuk!)。
(3)将最近查看的报告永久存储在会话中。
其他人怎么做这种事情?建议的做法是什么?
答案 0 :(得分:3)
不,绝对没有。当且仅当您之后立即重定向时,将某些内容存储到TempData中,因为TempData仅存在一次重定向。如果您在GET操作中将某些内容存储到TempData中然后呈现视图,那么例如来自此视图的AJAX请求将终止TempData,并且您将不会在POST请求中获取值。我的问题是,我是否以正确的方式将报告数据存储在TempData中?
正确的模式如下(无TempData
):
public ActionResult Report(DateTime? date)
{
if (!date.HasValue)
{
date = DateTime.Now;
}
// Clear the ModelState so that the date is displayed in the correct format as specified by the DisplayFormat attribute on the model
ModelState.Clear();
// Expensive call to database to retrieve the report data
ReportModel model = DataAdapter.Convert(this.reportService.GetReport((DateTime)date));
return View(model);
}
[HttpPost]
public ActionResult Report(ReportModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("Report", new { date = model.Date });
}
else
{
// Redisplay the view, the user inputted value for date will be loaded from ModelState
// TODO: query the database/cache to refetch any fields that weren't present
// in the form and that you need when redisplaying the view
return View(model);
}
}
(1)从HttpPost操作再次调用服务层 (由于验证,我宁愿不再进行另一次数据库调用 失败只是为了重新显示表单,因为它似乎效率低下)。我想我 可以在服务层实现缓存以避免数据库 往返......
这正是你应该做的。如果您在优化这些查询时遇到问题,或者在每个POST请求中遇到您的问题,那么就会缓存这些结果。数据库现在是超优化的,并且设计用于完成此操作(当然不要滥用,在适当的列上定义索引并且性能应该很好)。但是,如果您的网站要求很高,并且有很多请求和用户,那么缓存当然是避免访问数据库的最佳方法。
(2)在表格中使用隐藏的输入(yuk!)。
Yuk,我同意,但可以在你没有很多的情况下工作。
(3)将最近查看的报告永久存储在会话中。
不,避免会话。 Session是可扩展和无状态应用程序的敌人。