APS.NET MVC + EF (11)---过滤器

APS.NET MVC + EF (11)---过滤器

过滤器本质就是对动作方法的执行过程进行干预,这种干预可以影响动作方法执行的各个过程。ASP.NET MVC 提供了4种类型的接口,并在接口中定义了各种成员,代表代码执行的各个阶段,这些接口和成员如表11-1所示。

表11-1 常见过滤器接口

过滤器类型

接口

默认实现

描述

Action

IActionFilter

ActionFilterAttribute

在动作方法之前及之后运行

Result

IResultFilter

ActionFilterAttribute

在动作结果被执行之前和之后运行

AuthorizationFilter

IAuthorizationFilter

AuthorizeAttribute

首先运行,在任何其它过滤器或动作方法之前

Execption

IExceptionFilter

HandleErrorAttribute

只在另一个过滤器、动作方法、动作结果弹出异常时运行

   

当动作方法同时应用了继承自这些特性的过滤器后,实际的执行过程如图11-1所示。

 

   

 

图11-1 过滤器执行过程

   

图11-1中流程并没有列出 OnException() 方法的执行时机,事实上,在执行流程中只要任何环节出现异常,就会执行 OnException()方法。

11.1 过滤器的使用

ASP.NET MVC 的这种过滤器机制,实际是体现了一种 AOP(面向切面) 设计思想,当需要为动作方法进行干预时,不需要变动动作方法内部的代码,就可以扩张横向的行为。在实际开发中,只需要继承这些接口,实现自定义的特性,并在动作方法上应用自定义的特性,就可以扩展动作方法的能力。实现自定义的过滤器特性,需要满足两个要求。一是实现表11-1中任意的接口,二是继承FilterAttribute,标识它是一个过滤器。接下来介绍自定义过滤器的用法。

   

11.1.1 Action 过滤器

在ASP.NET MVC 项目中创建文件夹Filter,然后新建类MyActionFilterAttribute(为了遵循默认的约定,名称以Attribute结尾),继承自ActionFilterAttribute类。ActionFilterAttribute类有如下4个方法。

public virtual void OnActionExecuted(ActionExecutedContext filterContext);

public virtual void OnActionExecuting(ActionExecutingContext filterContext);

public virtual void OnResultExecuted(ResultExecutedContext filterContext);

public virtual void OnResultExecuting(ResultExecutingContext filterContext);

MyActionFilterAttribute.cs 类的代码如示例1所示。

示例1

public class MyActionFilterAttribute : ActionFilterAttribute

{

//Action执行之前

public override void OnActionExecuting(ActionExecutingContext filterContext)

{

//1、获取请求的类名和方法名

string strController = filterContext.RouteData.Values["controller"].ToString();

string strAction = filterContext.RouteData.Values["action"].ToString();

   

//2、用另一种方式获取请求的类名和方法名

string strController2 = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;

string strAction2 = filterContext.ActionDescriptor.ActionName;

   

filterContext.HttpContext.Response.Write("控制器:" + strController + "<br/>");

filterContext.HttpContext.Response.Write("控制器:" + strController2 + "<br/>");

filterContext.HttpContext.Response.Write("Action:" + strAction + "<br/>");

filterContext.HttpContext.Response.Write("Action:" + strAction2 + "<br/>");

filterContext.HttpContext.Response.Write("Action执行前:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");

base.OnActionExecuting(filterContext);

   

}

//Action执行之后

public override void OnActionExecuted(ActionExecutedContext filterContext)

{

filterContext.HttpContext.Response.Write("Action执行后:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");

base.OnActionExecuted(filterContext);

}

}

对于过滤器,我们可以把它们加在3个地方,一个是控制器上面(控制器下面的所有Action),一个是Action上面(指定标识的Action),另一个就是全局位置(所有控制器中的Action)

在控制器上代码如下:

[MyActionFilter]

public ActionResult Index()

{

return View();

}

11.1.2 Result 过滤器

在Filter文件夹中新建MyResultFilterAttribute类,继承ActionFilterAttribute。如示例2所示。

示例2

public class MyResultAttribute: ActionFilterAttribute

{

// 加载"视图"前执行

public override void OnResultExecuting(ResultExecutingContext filterContext)

{

filterContext.HttpContext.Response.Write("加载视图前执行 OnResultExecuting" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");

base.OnResultExecuting(filterContext);

}

// 加载"视图"后执行

public override void OnResultExecuted(ResultExecutedContext filterContext)

{

filterContext.HttpContext.Response.Write("加载视图后执行 OnResultExecuted" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + "<br/>");

base.OnResultExecuted(filterContext);

}

}

这里把MyResultFilter过滤器加在控制器上面,相当于给Home控制器中的所有的Action方法添加了MyResultFilter过滤器。如下代码所示。

[MyResultFilter]

public class HomeController : Controller

{

[MyActionFilter]

public ActionResult Index()

{

return View();

}

}

   

11.1.3 AuthorizeAttribute过滤器

创建MyAuthorizeAttribute类,继承AuthorizeAttribute类。如示例3所示。

示例3

public class MyAuthorizeAttribute: AuthorizeAttribute

{

public override void OnAuthorization(AuthorizationContext filterContext)

{

filterContext.HttpContext.Response.Write("OnAuthorization<br/>");

//注释掉父类方法,

//因为父类里的OnAuthorization方法会调用ASP.NET的授权验证机制

//base.OnAuthorization(filterContext);

}

}

在控制器Home中的Index上添加MyAuthorize过滤器。

[MyActionFilter]

[MyAuthorize]

public ActionResult Index()

{

return View();

}

通常Authorize过滤器也是在全局过滤器上面的,主要用来做登录验证或者权限验证,在App_Start目录下的FilterConfig类的RegisterGlobalFilters方法中添加:

public class FilterConfig

{

public static void RegisterGlobalFilters(GlobalFilterCollection filters)

{

filters.Add(new HandleErrorAttribute());

//添加全局授权过滤器

filters.Add(new MyAuthorizeAttribute());

}

}

在全局中注册过滤器,则所有控制器的所有行为(Action)都会执行这个过滤器。

   

11.1.4 Exception过滤器

创建MyHandleErrorAttribute类,继承HandleErrorAttribute类。如示例4所示。

示例4

public class MyHandleErrorAttribute: HandleErrorAttribute

{

public override void OnException(ExceptionContext filterContext)

{

//1、获取异常对象

Exception ex = filterContext.Exception;

//2、记录异常日志 (将错误信息利用IO保存到文件)

 

//3、重定向友好页面

filterContext.Result = new RedirectResult("~/error.html");

//4、标记异常已经处理完毕

filterContext.ExceptionHandled = true;

 

base.OnException(filterContext);

}

}

在Action上面添加MyHandleError过滤器,如下所示。

[MyHandleError]

public ActionResult GetErr()

{

int a = 0;

int b = 1 / a;

return View();

}

运行会自动跳转到error.html页面。

如果页面没有跳转,就需要去Web.config配置文件中的<system.web>节点下面添加如下配置节点,开启自定义错误:

<customErrors mode="On"></customErrors>

   

通常这样的异常处理是放在全局过滤器上面的,只要任意Action方法报错就会执行MyHandleError过滤器中的代码。

修改App_Start目录下面的FilterConfig类:

public class FilterConfig

{

public static void RegisterGlobalFilters(GlobalFilterCollection filters)

{

//添加全局授权过滤器

filters.Add(new MyAuthorizeAttribute());

//添加全局异常处理过滤器

filters.Add(new MyHandleErrorAttribute());

}

}

Global.asax下的代码:

public class MvcApplication : System.Web.HttpApplication

{

protected void Application_Start()

{

App_Start.AutoMapperConfig.Config();

   

AreaRegistration.RegisterAllAreas();

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

RouteConfig.RegisterRoutes(RouteTable.Routes);

BundleConfig.RegisterBundles(BundleTable.Bundles);

}

}

   

11.2 基于Form的身份验证

   

身份验证流程

一、用户登录

  1、验证表单:ModelState.IsValid

  2、验证用户名和密码:通过查询数据库验证

  3、如果用户名和密码正确,则在客户端保存Cookie以保存用户登录状态:SetAuthCookie

    1):从数据库中查出用户名和一些必要的信息,并把额外信息保存到UserData中

    2):把用户名和UserData保存到 FormsAuthenticationTicket 票据中

    3):对票据进行加密 Encrypt

    4):将加密后的票据保存到Cookie发送到客户端

  4、跳转到登录前的页面

二、验证登录

  1、在Global中注册PostAuthenticateRequest事件函数,用于解析客户端发过来的Cookie数据

    1):通过 HttpContext.Current.User.Identity 判断用户是否登录(FormsIdentity,IsAuthenticated,AuthenticationType)

    2):从HttpContext 的Request的Cookie中解析出Value,解密得到 FormsAuthenticationTicket 得到UserData

  2、角色验证

    在Action加入 Authorize特性,可以进行角色验证

    在 HttpContext.Current.User 的 IsInRole 方法进行角色认证(需要重写)

   

   

   

   

   

posted @ 2019-05-15 11:35 高原&秃鹫 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ASP.NET MVC是一种面向Web应用程序的框架,它可以用于构建图书管理系统。 要实现一个图书管理系统,首先需要创建一个MVC的项目。在项目中,可以使用Model来表示图书的属性,如书名、作者、出版社等。可以使用View来展示图书的信息,如图书列表、图书详情等界面。还可以使用Controller来处理用户的请求,如添加图书、编辑图书、删除图书等操作。 在图书管理系统中,可以创建一个图书控制器来处理图书的相关操作。比如,可以创建一个方法来展示图书列表的视图,一个方法来接收用户添加图书的请求并保存到数据库,一个方法来处理用户删除图书的请求等等。这些方法可以使用MVC框架提供的特性如模型绑定、动作过滤器、路由等来增强系统的功能和灵活性。 在实现图书管理系统时,还需要使用数据库来存储图书的信息。可以使用Entity Framework等ORM工具来简化与数据库的操作。通过Entity Framework,可以很方便地创建图书实体并将其映射到数据库中的表中。 此外,还可以利用MVC框架提供的身份验证和授权功能来实现图书管理系统的用户认证和授权的功能。比如,可以使用ASP.NET Identity来管理用户和角色,限制只有管理员角色才能进行图书添加、编辑和删除等操作。 总结来说,使用ASP.NET MVC框架可以很方便地实现一个图书管理系统。通过合理的设计和利用MVC框架提供的特性,可以让系统更加健壮、灵活和易于维护。 ### 回答2: ASP.NET MVC框架是一种用于构建Web应用程序的开发模式,它基于ASP.NET平台。图书管理系统是一种常见的应用程序,用于管理图书馆的图书借阅、归还、查询等功能。 在ASP.NET MVC框架中,可以通过以下步骤实现图书管理系统: 1. 模型层:定义图书、图书馆、图书管理员等实体类,用于表示系统中的数据。可以使用Entity Framework或其他ORM框架来管理数据库操作。 2. 控制器层:编写控制器类来处理请求和响应。例如,可以有一个图书控制器,包含借阅、归还、查询图书等操作的方法。 3. 视图层:创建图书管理系统的界面,使用HTML、CSS和JavaScript等前端技术来构建用户界面。可以使用Razor视图引擎来生成服务器端的动态网页内容。 4. 路由配置:配置路由规则,将URL与相应的控制器和操作方法关联起来。例如,可以设置"/books/{id}"对应于图书控制器中的查询图书操作。 5. 身份验证和授权:为图书管理员和读者提供不同的权限,限制其对系统功能的访问。可以使用ASP.NET身份验证和授权机制来实现。 6. 数据库设计:设计图书管理系统的数据库结构,包括图书、读者、借阅记录等表。使用数据库迁移工具来管理数据库版本和脚本。 7. 日志记录和异常处理:在系统中实现日志记录和异常处理,帮助开发人员快速定位和修复问题。 通过以上步骤,使用ASP.NET MVC框架可以轻松地实现一个图书管理系统。开发人员可以借助框架提供的功能,高效地开发和维护系统,同时提供良好的用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值