ASP.NET MVC3学习笔记五(Controller)

一、 操作过滤器

一个操作方法一旦被选中就会立即执行,并且如果它返回一个结果,返回的结果也会随后执行;操作过滤器允许开发人员以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的名称;

posted @ 2013-02-25 23:22  RegicideGod  阅读(...)  评论(...编辑  收藏