一、 操作过滤器
一个操作方法一旦被选中就会立即执行,并且如果它返回一个结果,返回的结果也会随后执行;操作过滤器允许开发人员以4种方式参与操作和结果执行管道权:授权、操作前后处理、结果前后处理、错误处理。
A、在MVC中处理身份验证:
比如某个页面需要登录后才能访问:
首先在验证登录成功后,保存票据信息;
public ActionResult SaveKey() { FormsAuthentication.SetAuthCookie("Admin", false); }
在需要验证的action上加上验证的filter即可
[Authorize] public ActionResult Index() { ViewBag.Message = "欢迎使用 ASP.NET MVC!"; return View(); }
如果整个controller中的action都需要验证是否登录,直接在controller中加验证标记就行;
[Authorize(Users="Admin")] public class SuperController:Controller { }
此处做一个空的supercontroller可以作为基类的controller,这样所有其他的controller继承自supercontroller即可以验证相应权限;
B、操作前后处理、结果前后处理、错误处理
操作前后处理:IActionFilter
结果前后处理:IResultFilter
错误处理:IExceptionFilter
实现自定义的Attribute必须继承FilterAttribute并且实现上面的三种filter中的一种;
比如我们实现错误处理的IExceptionFilter
public class CatchException : FilterAttribute, IExceptionFilter { public static readonly ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); public void OnException(ExceptionContext filterContext) { log.Debug("错误信息", filterContext.Exception); } }
使用的时候同授权过滤器一样,在action上加[CatchException]即可;
基本上就可以很容易的做到不在controller中做一个try catch操作就可以写异常到日志文件;同理写到supercontroller中的基类效果更佳;
二、 实现自定义的返回结果
比如我们执行一个action的时候会返回return View()这样的写法,这个是系统已经定义好的,我们想返回自己定义的ViewResult,就可以定义一个类继承ActionRuesult即可;
public class XmlResult:ActionResult { private object data; public XmlResult(object data) { this.data = data; } public override void ExecuteResult(ControllerContext context) { var serializer = new XmlSerializer(data.GetType()); var response = context.HttpContext.Response.OutputStream; context.HttpContext.Response.ContentType = "text/xml"; serializer.Serialize(response, data); } }
此时就可以使用return XmlResult(Obj)将一个实体对象转换为xml形式,返回给View模板;
三、 自定义View模板基类
我们的View下面的cshtml都是继承自System.Web.Mvc.WebViewPage类,我们也可以定义自己的视图基类;
比如定义一个CustomWebViewPage
public abstract class CustomWebViewPage<T>:WebViewPage<T> { public override HttpResponseBase Response { get { base.Context.Response.Write("this is test"); return base.Response; } } public override void Execute() { } }
在指向我们的的View即可;
在Views文件中有一个web.config【不是项目解决方案下的web.config】
<pages pageBaseType="MVC3Pro.Controllers.CustomWebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> </namespaces> </pages>
修改pageBaseType为刚才自定义的page即可;当有response请求的时候会自动进到customwebviewpage中;
四、Controller的另外用法
一般我们都是在controller中定义action,任何返回actionresult此类操作;其实也可以按如下定义:
public class SuperController:Controller { public void Index() { Response.Write("this is super"); } }
一样也可以访问到/Super/Index 同样也支持传参;回想一下上面的自定义actionresult,就大致可以明白,返回ActionResult是把respnnes的返回规范化了;
关于ActionResult的结构图和具体的功能描述可以参照http://www.cnblogs.com/mecity/archive/2011/06/29/2092042.html
异步Controller
我们一般用的Controller都是支持同步操作的Controller,比如我们一个页面有3个连接,每个连接的执行操作都是2s,同步操作就是要等待6s整个页面才加载完,如果使用异步操作就只要2s就可以完成;异步的Controller在实际的应用中,主要还是一些页面请求过多时,采用异步加载,当然会增加服务器的负载;
一般的Controller都是直接继承Controller如果是异步的Controller则要继承AsyncController;
public class Test1Controller : AsyncController { public void NewsAsync() { AsyncManager.OutstandingOperations.Increment(); AsyncManager.Parameters["news"] = "test"; AsyncManager.OutstandingOperations.Decrement(); Thread.Sleep(2000); } public ActionResult NewsCompleted(string news) { return Content(news); } }
我们访问的时候只需要通过/Test1/News即可;并且我们最终响应请求的只是NewsCompleted这个Action,里面的参数则是在NewsAsync中定义的参数组news的名称