有时,我们需要保留整个模型,并在动作甚至控制器之间进行转移。在会话中存储模型是针对此类需求的良好解决方案。如果将其与MVC强大的模型绑定功能结合在一起,我们将获得优雅的方法。我们可以通过三个简单的步骤创建基于通用会话的模型绑定:
第一步:创建模型活页夹
自己创建一个模型绑定器。我个人在/ Infrastructure / ModelBinders文件夹中创建了SessionDataModelBinder类。
using System;
using System.Web.Mvc;
public class SessionDataModelBinder<TModel>
: IModelBinder
where TModel : class
{
private string SessionKey { get; set; }
public SessionDataModelBinder(string sessionKey)
{
if (string.IsNullOrEmpty(sessionKey))
throw new ArgumentNullException(nameof(sessionKey));
SessionKey = sessionKey;
}
public object BindModel(
ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
// 从会话中获取模型
TModel model = controllerContext
.HttpContext
.Session[SessionKey] as TModel;
// 如果在会话中找不到模型,请创建并存储模型
if (model == null)
{
model = Activator.CreateInstance<TModel>();
controllerContext.HttpContext.Session[SessionKey] = model;
}
// 退货模型
return model;
}
}第二步:注册活页夹
如果我们有如下模型:
public class ReportInfo
{
public int ReportId { get; set; }
public ReportTypes TypeId { get; set; }
}
public enum ReportTypes
{
NotSpecified,
Monthly, Yearly
}我们可以在Application_Start方法的Global.asax中为此模型注册基于会话的模型绑定器:
protected void Application_Start()
{
.........
// 模型粘合剂。
// 记住要选择唯一的SessionKey
ModelBinders.Binders.Add(typeof(ReportInfo),
new SessionDataModelBinder<ReportInfo>("ReportInfo"));
}第三步:使用它!
现在,只需将参数添加到操作中,我们就可以从此模型绑定程序中受益:
public class HomeController : Controller
{
public ActionResult Index(ReportInfo reportInfo)
{
// 只需设置属性
reportInfo.TypeId= ReportTypes.Monthly;
return View();
}
public ActionResult About(ReportInfo reportInfo)
{
//reportInfo.TypeIdis现在每月,因为我们设置了
// 它以前在索引操作中。
ReportTypes currentReportType = reportInfo.TypeId;
return View();
}
}