一.前言

继前面四篇ASP.NET MVC的随笔,我们继续向下学习。上一节我们学习了关于控制器的使用,本节我们将要学习如何使用过滤器控制用户访问页面。

二.正文

以下的示例建立在ASP.NET MVC 4之上(VS2012)

1.授权过滤器

只要涉及用户的网站,都一定会涉及到什么权限的用户可以访问哪个页面。对于新手而言可能都在每个页面中单独写这个功能方法,导致的后果就是大量重复的代码,并且不便于以后的变动。有用一定经验之后,就会采用集中控制的方式,让所有的页面先执行特定的方法去判断,这样的优点就是减少了代码的重复,同时也能够灵活的配置。但是对于某些拥有特殊需求的页面就有点力所不能及,而且这种权限判断的代码会和页面的逻辑代码混为一体,难以区分。而今天介绍的授权过滤器是采用注解属性的方式去控制每个动作,并且可以灵活的配置。

首先我们在网站根目录新建一个Filter文件夹,在其中新建一个CustAuthorizeAttribute类,类中的具体代码如下所示

 namespace MvcStudy.Filter
{
public class CustAuthorizeAttribute : AuthorizeAttribute
{
private string[] roles; public CustAuthorizeAttribute(params String[] role)
{
roles = role;
} protected override bool AuthorizeCore(HttpContextBase httpContext)
{
String role = httpContext.Request.QueryString["role"];
if (role != null)
{
return roles.Contains(role);
}
return base.AuthorizeCore(httpContext);
}
}
}

通过上面的代码我们知道这个过滤器将会在使用时要求使用者传入可以访问的角色有哪些,其中最终的是AuthorizeCore方法,该方法是负责判断当前的请求是有具有权限,这里我们为了演示,所以直接根据查询字符串的role的值来判断。

既然我们已经有了过滤器,下面我们新建一个Home控制器,并在Views下新建一个Home文件夹,同时在Home文件夹下新建名为Index的视图以及List的视图。接着我们打开Home控制器。

在其中写入如下代码

 namespace MvcStudy.Controllers
{
public class HomeController : Controller
{
[CustAuthorize("vip")]
public ActionResult Index()
{
return View();
} [CustAuthorize("admin")]
public ActionResult List()
{
return View();
}
}
}

我们可以看到笔者将Index动作规定为只有rolevip才能访问,而List则是admin。接着我们运行项目,浏览器会默认打开http://localhost:7575/(端口请根据实际情况而定),但是你会发现你将会被转移到http://localhost:7575/Account/Login?ReturnUrl=%2f这个页面,因为项目中我们并没有新建这个视图,所以会报404错误。而这个是被通过授权后ASP.NET MVC默认的行为,当然我们可以改变这个行为,下面我们来改变这个行为,让其直接跳转到Login视图,修改CustAuthorizeAttribute类。

代码如下所示:

 namespace MvcStudy.Filter
{
public class CustAuthorizeAttribute : AuthorizeAttribute
{
private string[] roles; public CustAuthorizeAttribute(params String[] role)
{
roles = role;
} protected override bool AuthorizeCore(HttpContextBase httpContext)
{
String role = httpContext.Request.QueryString["role"];
if (role != null)
{
return roles.Contains(role);
}
return base.AuthorizeCore(httpContext);
} protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
UrlHelper url = new UrlHelper(filterContext.RequestContext);
filterContext.Result = new RedirectResult("/Login");
}
}
}

其中关键的是我们重写了HandleUnauthorizedRequest方法,这个方法只有在AuthorizeCore返回false情况才会调用,同时该方法的参数中有一个Result属性,该属性是将最终的处理结果赋给它。

重新编译,我们继续访问默认的路径,这个时候我们可以发现转移的路径已经变成了http://localhost:7575/Login,到这里我们已经可以处理授权失败的情况了,现在我们就要开始测试几个正确的结果首先是Index,我们只需要访问该路径即可http://localhost:7575/Home/Index?role=vip(同http://localhost:7575/?role=vip),如果要访问List,我们就需要访问这个路径http://localhost:7575/Home/List?role=admin,通过这个简单的例子,我们就可以知道在ASP.NET MVC中是通过何种方式去控制用户访问页面的权限。

2.异常过滤器

在我们的开发过程我们很多的时间都在修改异常,防止异常的发生。但是在实际的运行过程中总会发生很多我们未曾发现的问题,以及其他恶意的攻击。这个时候我们就需要一个统一的机制可以控制并处理这些异常,或许我一说到异常很多人都会联想到try{}catch{},的确没错,异常的捕获是用他们,但是你有没有想过,如果一个网站导出充斥着try{}catch{},不仅仅是不美观,同时也能以控制。而ASP.NET MVC为我们提供了异常过滤器,可以为每个动作添加这个注解属性,这样我们就可以灵活的控制并处理这些异常。

首先我们在Filter文件中新建一个CustExceptionAttribute类,并在其中写入如下的代码

 namespace MvcStudy.Filter
{
public class CustExceptionAttribute : FilterAttribute , IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled)
{
filterContext.Result = new RedirectResult("error.html");
filterContext.ExceptionHandled = true;
}
}
}
}

我们可以看到这里我们依然还是用Result来将我们处理后的结果赋值给它,但是我们这里还判断了ExceptionHandled属性,这个属性的含义是如果其他的异常过滤器已经处理了该异常,则该属性的值为true,为了能够适应大的范围,所以笔者这里建议读者也要先判断是否已经有其他的异常过滤器已经处理过这个异常了。

下面我们在Home控制器中的Index动作中使用:

 namespace MvcStudy.Controllers
{
public class HomeController : Controller
{
[CustException()]
public ActionResult Index()
{
throw new NullReferenceException();
return View();
}
}
}

这个时候我们访问http://localhost:7575/将会跳转至http://localhost:7575/error.html页面(因为笔者没有建这个页面所以会显示404),但是读者可以看到这里我仅仅只是根据异常跳转到一个特定的页面,其实ASP.NET MVC中已经默认为我们实现了这个注解属性,这个注解属性就是HandleError类,我们只需要传入需要捕获的异常类型,以及对应的页面即可。

下面我们修改Home控制器的Index动作:

 namespace MvcStudy.Controllers
{
public class HomeController : Controller
{
[HandleError(ExceptionType=typeof(NullReferenceException),View="error")]
public ActionResult Index()
{
throw new NullReferenceException();
return View();
}
}
}

然后我们重新编译,并访问页面,会发现页面没有按照我们的预想跳转到特定的页面而是直接显示了错误的详情。这是因为ASP.NET MVC默认情况下没有开启自定义异常处理,所以就会出现这个默认的页面,下面我们修改Web.Config在其中添加如下的配置

这时我们重新编译刷新页面,但是我们会发现页面会有内容,因为这个页面调用的是Views/Shared/Error.cshtml页面。

未完待续…

ASP.NET MVC学习之过滤器篇(1)的更多相关文章

  1. ASP.NET MVC学习之过滤器篇(2)

    下面我们继续之前的ASP.NET MVC学习之过滤器篇(1)进行学习. 3.动作过滤器 顾名思义,这个过滤器就是在动作方法调用前与调用后响应的.我们可以在调用前更改实际调用的动作,也可以在动作调用完成 ...

  2. ASP.NET MVC学习之控制器篇扩展性

    原文:ASP.NET MVC学习之控制器篇扩展性 一.前言 在之前的一篇随笔中已经讲述过控制器,而今天的随笔是作为之前的扩展. 二.正文 1.自定义动作方法 相信大家在开发过程一定会遇到动作方法的重名 ...

  3. ASP.NET MVC学习之控制器篇

    一.前言 许久之后终于可以继续我的ASP.NET MVC连载了,之前我们全面的讲述了路由相关的知识,下面我们将开始控制器和动作的讲解. ASP.NET MVC学习之路由篇幅(1) ASP.NET MV ...

  4. ASP.NET MVC学习之视图篇(2)

    继ASP.NET MVC学习之视图(1)学习 4.HTML辅助器 虽然在ASP.NET MVC中我们已经摆脱了ASP.NET的控件,但是对于页面中需要循环标签的情况依然还是存在,可能很多人认为用for ...

  5. ASP.NET MVC学习之控制器篇(二)

    原文链接:http://www.asp.net/learn/mvc/ 这篇教程探索了ASP.NET MVC控制器(controller).控制器动作(controller action)和动作结果(a ...

  6. ASP.NET MVC学习之视图篇(1)

    一.前言 不知道还有多少读者从第一篇开始一直学习到如今,笔者也会一直坚持将ASP.NET MVC的学习完美的结束掉,然后开始写如何配合其他框架使用ASP.NET MVC的随笔.当然笔者后面的随笔如果没 ...

  7. ASP.NET MVC学习之路由篇(3)

    根据路由输出链接 既然是网站开发自然少不了链接,我们已经学会了强大的路由,但是还缺少一步就是能够将这些路由的路径输出到页面,下面我们就开始学习如何输出路由路径. 首先我们的路由注册部分如下所示: 1 ...

  8. ASP.NET MVC学习之路由篇(2)

    7.解决与物理路径的冲突 当发送一个请求至ASP.NET MVC时,其实会检查网站中存不存在这个请求的物理路径文件,如果存在的话,就会直接将这个物理文件返回.但是有时候我们需要它执行控制器的某个方法, ...

  9. ASP.NET MVC学习之路由篇(1)

    1.基本路由 RouteConfig.cs: 1 public class RouteConfig 2 { 3 public static void RegisterRoutes(RouteColle ...

随机推荐

  1. android自定义圆形图片和遇到的问题

    画圆遇到的问题:图片单位不一样,导致图片只能显示出圆的一部分:看代码: public class MyCircleIamge extends ImageView { private Context c ...

  2. linux 驱动学习笔记02--应用实例:在内核中新增驱动代码目录和子目录

    下面来看一个综合实例,假设我们要在内核源代码 drivers 目录下为 ARM 体系结构新增如下用于 test driver 的树型目录:| --test  | -- cpu  | -- cpu.c ...

  3. 怎么提高ArcSDE 写入地理数据库的效率

    link: http://blog.csdn.net/linghe301/article/details/20900615 2014-03-14 09:20 2686人阅读 评论(6) 收藏 举报   ...

  4. 2.Mybatis入门程序(单表的增删改成)

    这里讲的单表的增删改查,是由mapper代理的增删改查,先来看看步骤: 1.jar包的导入 2.配置全局的配置文件 3.建立接口 4.编写mapper.xml 5.测试 工程结构:这个你们自己可以调整 ...

  5. Get the Uniqueid of Action Originate in the AMI

    [asterisk-users] Get the Uniqueid of Action Originate in the AMI Adolphe Cher-Aime acheraime at gmai ...

  6. mybatis(二)接口编程 、动态sql 、批量删除 、动态更新、连表查询

    原理等不在赘述,这里主要通过代码展现. 在mybatis(一)基础上,新建一个dao包,并在里面编写接口,然后再在xml文件中引入接口路径,其他不变,在运用阶段将比原始方法更节约时间,因为不用再去手动 ...

  7. .NET Remoting获取配置通道:

    接上文: public static string ChannelManagerUrl        {            get            {                retu ...

  8. 装完RHEL7后,重新开机启动后显示:Initial setup of CentOS Linux 7 (core) 提示license报错

    装完RHEL7后,重新开机启动后显示: 1) [x] Creat user 2) [!] License information (no user will be created) (license ...

  9. java核心知识点学习----多线程并发之线程同步

    1.什么是线程同步? 多线程编程是很有趣的事情,它很容易出现"错误情况",这种情况不是由编码造成的,它是由系统的线程调度造成的,当使用多个线程来访问同一个数据时,很容易出现&quo ...

  10. 手动开启/关闭Oracle数据库

    @echo off@echo 启动/关闭数据库set /p flag=您是否要启动数据库?(是按Y启动,否按N关闭) goto answer%flag% goto end :answery echo ...