ASP.NET MVC 中解决Session,Cookie等依赖的方式

66 篇文章 3 订阅

目录

介绍

使用Filter方式

Filter在MVC生命周期中的位置

Filter常见的应用场景

Filter的执行顺序

MVC中常见的对Session,Cookie的依赖

使用Filter解除依赖

使用Model Binding方式

什么是Model Binding?

自定义Model Binding

总结


介绍

本文将分别介绍在MVC中使用Filter和Model Binding两种方式来说明如何解除对Session,Cookie等的依赖。当然也会适当对Filter在MVC请求的生命周期中的作用和角色,使用场景等作下简单的说明。

 

使用Filter方式

Filter在MVC生命周期中的位置

 

如上图所示,一个完成的MVC的生命周期分为5个步骤, 对应图例中的1~5。

  1. IIS中传递请求到程序
  2. MVC根据Routing来选择由哪个Controller/Action来处理
  3. Controller调用Model(业务逻辑)来处理数据
  4. Controller选择一个View, 同时把需要呈现的数据交给View Engine呈现
  5. 最后,返回最终的Response到客户端

Filter在MVC的生命周期中的角色就像是一个一个的截面,在MVC的处理过程中,拦截请求。

Filter分为:

Authorization filters——需要实现IAuthorizationFilter接口,用于验证处理验证相关的操作

Action filters——需要实现IActionFilter接口. 在Action处理的开始和结束做拦截操作

Result filters——需要实现IResultFilter接口. 在View呈现前和呈现后做处理

Exception filters——需要实现IExceptionFilter接口,只要是添加了Exception Filter的请求中出现异常,都会被拦截

每个Filter的作用时机,对应于上图中的2a, 2b, 4a, 4b。

 

Filter常见的应用场景

下面是个人在开发中,常用到的Filter处理:

  • 权限验证

使用Authorization filters,拦截请求,在进入到Controller处理之前,验证用户是否登录或者登录用户是否有权限访问改页面。

如果合法,就继续交由Controller处理,如果非法,中断流程,跳转到登录页面。

 

  • 日志记录

通过Action Filter跟踪记录Action处理开始的时间,结束时间,访问的具体Controller和Action, 参数,访问者ip等信息。

 

  • 异常处理

异常处理Exception filter能够在发生异常的时候,记录异常信息。如果是session过期引起的异常,则跳转到登录页面,如果是程序运行导致的无法处理异常,则跳转到友好的错误页面。

 

  • 提升SEO效果

每篇博客文章的meta信息能够帮助提高SEO效果,但是很多人对于填写keyword, description等信息觉得太繁琐。

可以使用Result filters,在最后呈现页面前,使用程序分析内容,提取keyword和description来,然后填充到meta信息中。

这样,每篇博客文章都能够有程序实现最佳的SEO效果,甚至生成一份SEO报告出来。

 

Filter的执行顺序

Filter之间执行的顺序,首先根据类型区分:

分别是Authorization filters, Action filters, Result filtersException Filter没有列入的原因是, 它是在发生异常的时候处理,没有特定的顺序。

当同时对一个类型的Filter的时候,执行顺序可以通过Filter的Order属性来排序。

 

MVC中常见的对Session,Cookie的依赖

在Web程序中,对于Session和Cookie等的使用是必不可少的。比如, 很多的Action的代码中,会要从Session中获取当前登录用户信息:

public ActionResult Index()
{
     var user = Session[“UserAccuont”];//从Session中获取当前登录用户的信息
     //send email
     var email = user.Email;
     …………
}

上面的Index方法的问题就是和Session耦合,很难单元测试。下面介绍如何使用Filter来解除对于Session的依赖。

 

使用Filter解除依赖

添加一个SessionUserParameterAttribute的Action Filter, 它的功能是:

从Session中取得User, 将取得的User赋值给Action中的参数sessionUser。

public class SessionUserParameterAttribute : ActionFilterAttribute
{
       public override void OnActionExecuting(ActionExecutingContext filterContext)
       {
           const string key = "sessionUser";

           if (filterContext.ActionParameters.ContainsKey(key))
           {
               filterContext.ActionParameters[key] = Session[“UserAccuont”];//为Action设置参数
           }

           base.OnActionExecuting(filterContext);
       }
}

改造后的Index Action方法如下:

[SessionUserParameter]
public ActionResult Index(UserAccount sessionUser)
{
     //send email
     var email = sessionUser.Email;
     …………
}

这样Index方法就解除了对于Session的依赖,而只是依赖于一个普通的实体类UserAccount。在单元测试中,只需要简单的构造一个UserAccount的对象就可以了。

 

使用Model Binding方式

什么是Model Binding?

Model Binding的作用就是将Request请求中包含的散乱参数,根据接受请求的Action方法的参数列表,自动智能地构建这些参数的过程。

 

自定义Model Binding

继承接口IModelBinder, 实现BindModel方法。

这个UserAccountModelBinder的作用就是从Session中取得UserAccount。(问题和Filter中提到的问题相同)

   public class UserAccountModelBinder : IModelBinder
   {
       public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
       {
           if(controllerContext.HttpContext.Session["UserAccuont"] != null)
           {
               return controllerContext.HttpContext.Session["UserAccuont"];
           }
           return null;
       }
   }

接下来,我们要为这个ModelBinder,添加到MVC的Model Binding设置中,使得它能够在MVC的生命周期中起作用。

在Global.asax.cs文件的Application_Start()方法中,添加UserAccountModelBinder。

protected void Application_Start()
{

    ………

    //凡是UserAccount类型的参数,都会使用UserAccountModelBinder来处理,也就是会从Session中取值

    ModelBinders.Binders.Add(typeof(UserAccount), new UserAccountModelBinder ());

}

改造后的Index方法如下:

public ActionResult Index(UserAccount sessionUser)
{
     //send email
     var email = sessionUser.Email;
     …………
}

上面就是全部的Model Binding解决问题的过程,希望能够帮助大家更好地理解MVC中的Model Binding。

 

总结

本文主要介绍了MVC中两种解决对Session,Cookie等依赖的方式,这两种方式可根据自己项目的需求具体选择使用哪种。其中Filter还有其他一些场景的使用,有兴趣的小伙伴也可以自己多多探索。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值