ASP.NET MVC 控制器

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

这里咱们有两个细节:cookie

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

2:如何肯定用那个方法。this

  路由:spa

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

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

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

  POCO(plain Old C# Object)blog

控制器类能够是一个普通的传统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;
        }
    }
相关文章
相关标签/搜索