ASP.NET MVC controller

We said in the first part. There are two steps to write a controller class: implement a class, and then add some public methods to the class, which can be found as a controller when the class is running, and these methods are found as operations.

Here we have two details:

1: How does the system know to instantiate that controller

2: How to determine which method to use.

Route:

1: It is found by traditional routing, 2: by characteristic routing, 3: by mixed routing strategy,

Traditional routing does not explain too much. Feature routing enables the URL template to be independent of the controller and operation used to process the request. In the future, even if the URL is modified, the code does not need to be refactored.

Mixed routes use the first two together, but note that the feature defines routes with higher priority than traditional routes.

  POCO(plain Old C# Object)

The Controller class can be a common traditional C object. If you want to be found, either the class name has the Controller suffix or the class is decorated with the Controller feature. POCO, in short, reduces overhead and / or memory usage.

 

Access HTTP context

The biggest problem of POCO is that there is no HTTP context, so we can implement it through ActionContext as follows:

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

Action filter

1: it is a piece of code running around the method, which can be used to modify and extend the behavior of the method itself.

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

It provides hooks to run code before and after operations. Access to the request and controller context within the filter, and read and modify parameters.

Each user-defined Controller that inherits the cobroller class will get the default implementation of the IActionFilter interface. , in fact, the base class Controller provides a pair of overridable methods, OnActionExecuting and OnActionExecuted. This means that each Controller class has an opportunity to decide what to do before, after or before the call to a given method. You only need to rewrite the method of the base class to achieve this function. Of course POCO does not

  

 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);
        }

  

 

Calculate how many milliseconds were performed

2: Classification of filters

The operation filter is only a filter called in the ASP.NET CORE pipeline. It can be divided into different types according to the actual tasks completed by the filter.

 

type describe
Authorization filter The first class filter running in the pipeline to determine whether the user making the request has the right to make the current request
Resource filter When authorized, runs before the rest of the pipeline and after the pipeline components, useful for caching
Action filter Run before and after controller method operation
Exception filter If registered, triggers when an unhandled exception occurs
Result filter Run before and after action method results

The filter can be applied to a single method, or to the entire controller class, affecting all the operation methods exposed by the controller. In contrast, after the global filter is registered at the start of the application, they will be automatically applied to any operation of any controller class.

① : add custom header

 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;
        }
        
    }

② Set requested culture

 [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;
        }
    }

It mainly checks a custom cookie named "Ou Culture" before the operation method, which contains the user's preferred language. If the cookie is not found, the filter defaults to the current Culture and assigns it to the current thread. Last global registration

③ : restrict methods to Ajax calls only

   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;
        }
    }

Tags: ASP.NET REST

Posted on Wed, 08 Jan 2020 05:43:07 -0800 by tkmk