• ASP.NET MVC 控制器


      上篇我们说到。编写控制器类的步骤可总结为两个:实现一个类,然后在该类中添加一些公有方法,在运行的该类的时候可作为控制器发现,而这些方法则作为操作被发现。

    这里我们有两个细节:

    1:系统如何知道实例化那个控制器

    2:如何确定用那个方法。

      路由:

    1:被传统的路由发现,2:通过特性路由发现,3:通过混合路由策略发现,

    传统路由不做过多解释。特性路由,可以让URL模版与处理请求时使用的控制器和操作保持独立,以后,即使URL进行修改,也不需要重构代码。

    混合路由则时前两者一起使用,不过注意的是,特性定义的路由比传统路由的优先级更高。

      POCO(plain Old C# Object)

    控制器类可以是一个普通的传统C#对象。如果想被发现,要么类名带有Controller后缀,要么用Controller特性修饰该类。POCO简单来说,它能减少开销和/内存占用量。

      访问HTTP上下文

      POCO最大的问题是没有HTTP上下文,那么我们可以通过ActionContext来实现如:

    public class PocoController
    {
        [ActionController]
        public ActionContext Context{get;set}
    ......  
    }

      操作筛选器

     1:它是围绕做方法运行的一段代码,可用于修改和扩展方法本身的行为。

    public interface IActionFilter
    {
       void OnActionExecuting(ActionExecutingContext filterContext);
       void OnActionExected(ActionExecutedContext filterContext);      
    }
    

      它提供了挂钩,在操作之前和之后运行代码。在筛选器内能够访问请求和控制器上下文,并且可以读取和修改参数。

    每个继承了Cobtroller类的,用户定义的控制器都会获得IActionFilter接口的默认实现。,事实上,基类Controller提供了一对可重写的方法,OnActionExecuting和OnActionExecuted。这就代表每个控制器类都有一个机会,用来决定在调用给定方法前,后或者调用方法前后做些什么,只需要重写基类的方法就能实现这种功能。当然POCO不具备.

      

     protected DateTime StartTime;
            public override void OnActionExecuting(ActionExecutingContext context)
            {
                var action = context.ActionDescriptor.RouteValues["Action"];
                if(string.Equals(action,"index",StringComparison.CurrentCultureIgnoreCase))
                {
                    StartTime = DateTime.Now;
                }
                base.OnActionExecuting(context);
            }
            public override void OnActionExecuted(ActionExecutedContext context)
            {
                var action = context.ActionDescriptor.RouteValues["Action"];
                if (string.Equals(action, "index", StringComparison.CurrentCultureIgnoreCase))
                {
                    var timeSpan = DateTime.Now-StartTime;
                    context.HttpContext.Response.Headers.Add(
                    "duration", timeSpan.TotalMilliseconds.ToString());
                    
                }
                base.OnActionExecuted(context);
            }
    

      

     计算执行了多少毫秒

    2:筛选器的分类

    :操作筛选器只是ASP.NET CORE 管道中调用的一种筛选器,按照筛选器实际完成的额任务,可分成不同的类型。

    类型 描述
    授权筛选器 管道中运行的第一个类筛选器,用来确定发出请求的用户是否有权发出当前的请求
    资源筛选器 当授权之后,在管道的其余部分之前以及管道组件之后运行,对于缓存很有用
    操作筛选器 在控制器方法操作之前和之后运行
    异常筛选器 如果注册,则在发生未处理异常时触发
    结果筛选器 在操作方法结果之前和之后运行

    可以将筛选器应用单独方法,也可以应用到整个控制器类,影响该控制器公开的所有操作方法,相对的,在应用程序启动时注册了全局筛选器之后,他们将自动应用到任何控制器类的任何操作。

    ①:添加自定义头

     public class HeaderAttribute:ActionFilterAttribute
        {
            public string Name { get; set; }
            public string Value { get; set; }
            public override void OnActionExecuted(ActionExecutedContext context)
            {
               if(!string.IsNullOrWhiteSpace(Name)&&!string.IsNullOrWhiteSpace(Value))
                {
                    context.HttpContext.Response.Headers.Add(Name, Value);
                }
                return;
            }
            
        }

    ② 设置请求的区域性

     [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple =false)]
        public class CultureAttribute:ActionFilterAttribute
        {
            public string Name { get; set; }
            public static string CookieName { get { return "_Culture"; } }
            public override void OnActionExecuting(ActionExecutingContext context)
            {
                var culture = Name;
                if (string.IsNullOrWhiteSpace(culture))
                    culture = GetSavedCultureOrDefault(context.HttpContext.Request);
    
                SetCultureOnThread(culture);
                base.OnActionExecuting(context);
            }
    
            private  static void SetCultureOnThread(string language)
            {
                var cultureInfo = new CultureInfo(language);
                CultureInfo.CurrentCulture = cultureInfo;
                CultureInfo.CurrentUICulture = cultureInfo;
            }
    
            private static string GetSavedCultureOrDefault(HttpRequest request)
            {
                var culture = CultureInfo.CurrentCulture.Name;
                var cookie = request.Cookies[CookieName] ?? culture;
                return culture;
            }
        }

    主要是在操作方法之前检查一个名为_Culture的自定义cookie,其中包含了用户首选的语言,如果没找到cookie,筛选器默认使用当前区域性,并赋值给当前的线程。最后全局注册

    ③:将方法限制只能Ajax调用

       public class AjaxOnlyAttribute:ActionMethodSelectorAttribute
        {
            public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action) => routeContext.HttpContext.Request.IsAjaxRequest();
    
        }
    public static class HttpRequestExtensions
        {
            public static bool IsAjaxRequest(this HttpRequest httpRequest)
            {
                if (httpRequest == null)
                    throw new ArgumentException("request");
                if (httpRequest.Headers != null)
                    return httpRequest.Headers["X-Requested-With"] == "XMLHttpRequest";
                return false;
            }
        }
  • 相关阅读:
    Makefile常用函数
    Source Insight 中的 Auto Indenting
    Git中的core.autocrlf选项
    [转] VMware中的Ubuntu无法通过桥接方式上网
    Git基础
    数据结构35:二叉树前序遍历、中序遍历和后序遍历
    数据结构34:二叉树前序遍历、中序遍历和后序遍历
    数据结构33:二叉树顺序存储和链式存储
    数据结构32:树存储结构
    数据结构31:树(Tree)详解
  • 原文地址:https://www.cnblogs.com/ccaa/p/12164379.html
Copyright © 2020-2023  润新知