原文:https://blog.csdn.net/mzl87/article/details/90580869

本文将分别介绍在MVC中使用Filter和Model Binding两种方式来说明如何解除对Session,Cookie等的依赖。

当然也会适当对Filter在MVC请求的生命周期中的作用和角色,使用场景等作下简单的说明。

一个完整的MVC的生命周期分为5个步骤, 对应图例中的1~5。

  • IIS中传递请求到程序
  • MVC根据Routing来选择由哪个Controller/Action来处理
  • Controller调用Model(业务逻辑)来处理数据
  • Controller选择一个View, 同时把需要呈现的数据交给View Engine呈现
  • 最后,返回最终的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 filters。Exception 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还有其他一些场景的使用,有兴趣的小伙伴也可以自己多多探索。
————————————————
版权声明:本文为CSDN博主「寒冰屋」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mzl87/java/article/details/90580869

ASP.NET MVC 中解决Session,Cookie等依赖的方式的更多相关文章

  1. ASP.NET MVC中的Session设置

    最近在ASP.NET MVC项目中碰到这样的情况:在一个controller中设置了Session,但在另一个controller的构造函数中无法获取该Session,会报"System.N ...

  2. ASP.NET MVC中的Session以及处理方式

    最近在ASP.NET MVC项目中碰到这样的情况:在一个controller中设置了Session,但在另一个controller的构造函数中无法获取该Session,会报"System.N ...

  3. ASP.NET MVC中controller和view相互传值的方式

    ASP.NET MVC中Controller向view传值的方式: ViewBag.ViewData.TempData 单个值的传递 Json 匿名类型 ExpandoObject Cookie Vi ...

  4. ASP.NET MVC中使用Session来保持表单的状态

    本篇实践在ASP.NET MVC 4下使用Session来保持表单的状态. 本篇的源码在这里: https://github.com/darrenji/KeepFormStateUsingSessio ...

  5. ASP.NET MVC中解决日志并发处理log4net

    本章主要内容是将异常信息写到队列中,然后通过线程写到文本文件中,速度非常快,没有阻塞和延迟加载 1.首先在Model中建一个类MyExceptionAttribute.cs public class ...

  6. 在ASP.NET MVC中如何预防Cookie的窃取攻击(转载)

    Cookie Cookie is a small piece of data sent by a web server to a web browser. The browser stores thi ...

  7. 关于在ASP.NET MVC 中使用EF的Code First的方式来读取数据库时的Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

    今天在做一个小网站的时候遇到很多问题唉,我还是个菜鸟,懂的也不多,今天一个表单的提交按钮用不了,都弄了几个小时唉.不过最后还是搞定了,还有浏览器有开发人员选项,不然我都不知道我还要继续排查多久哦,今天 ...

  8. 转载ASP.NET MVC中Session的处理机制

    本文章转载自 http://www.cnblogs.com/darrenji/p/3951065.html ASP.NET MVC中的Session以及处理方式   最近在ASP.NET MVC项目中 ...

  9. Asp.net MVC 中使用 Ninject 实现依赖注入

    松耦合.针对抽象编程.不针对实现编程是面向对象设计的原则.依赖注入就是,在一个类的内部,不通过创建对象的实例而能够获得实现了某个公开接口的对象引用.所谓的控制反转也是相同的意思.把依赖的创建转移到了使 ...

随机推荐

  1. Java实现 蓝桥杯 算法提高 天天向上(DP)

    试题 算法提高 天天向上 问题描述 A同学的学习成绩十分不稳定,于是老师对他说:"只要你连续4天成绩有进步,那我就奖励给你一朵小红花."可是这对于A同学太困难了.于是,老师对他放宽 ...

  2. Java实现 LeetCode 564 寻找最近的回文数(今天要GG在这道题了 头晕+题难(((φ(◎ロ◎;)φ))))

    564. 寻找最近的回文数 给定一个整数 n ,你需要找到与它最近的回文数(不包括自身). "最近的"定义为两个整数差的绝对值最小. 示例 1: 输入: "123&quo ...

  3. Java实现 LeetCode 491递增子序列

    491. 递增子序列 给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2. 示例: 输入: [4, 6, 7, 7] 输出: [[4, 6], [4, 7], [4, ...

  4. Java实现 LeetCode 284 顶端迭代器

    284. 顶端迭代器 给定一个迭代器类的接口,接口包含两个方法: next() 和 hasNext().设计并实现一个支持 peek() 操作的顶端迭代器 – 其本质就是把原本应由 next() 方法 ...

  5. Java实现蓝桥杯分金币

    分金币 圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币, 最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值. 比如,n=4,且4个人 ...

  6. Java实现矩阵相乘问题

    1 问题描述 1.1实验题目 设M1和M2是两个n×n的矩阵,设计算法计算M1×M2 的乘积. 1.2实验目的 (1)提高应用蛮力法设计算法的技能: (2)深刻理解并掌握分治法的设计思想: (3)理解 ...

  7. java实现第七届蓝桥杯机器人塔

    机器人塔 X星球的机器人表演拉拉队有两种服装,A和B. 他们这次表演的是搭机器人塔. 类似: A B B A B A A A B B B B B A B A B A B B A 队内的组塔规则是: A ...

  8. class 类前向声明

    /*   使用前向引用声明虽然可以解决一些问题,但它并不是万能的.需要注意的是,   尽管使用了前向引用声明,但是在提供一个完整的类声明之前,不能声明该类的对象,   也不能在内联成员函数中使用该类的 ...

  9. 仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表'xxxx'中的标识列指定显式值

    执行以下sql INSERT INTO [Country] VALUES (, N'中国', N'China', N'CN'); 提示错误 仅当使用了列列表并且 IDENTITY_INSERT 为 O ...

  10. 手把手教你用redis实现一个简单的mq消息队列(java)

    众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...