zoukankan      html  css  js  c++  java
  • ASP.NET MVC 使 Controller 的 Action 只接受 Ajax 请求。

    首先,ajax 请求跟一般的 web 请求本质是相同的,都是 http 请求。理论上服务器端是无法区分该次请求是不是 ajax 请求的,但是,既然标题都已经说了,那么肯定是有办法做的。

    在 ajax 请求的请求报文里,往往会包含这么一条:X-Requested-With = XMLHttpRequest

    这在各大的 javascript 框架上也是这么做的。

    而服务器端就可以根据这一点来判别,该次的请求是否是 ajax 请求。

    而在 ASP.NET MVC 里,也有一个扩展方法:

     1 namespace System.Web.Mvc
     2 {
     3     // 摘要: 
     4     //     表示一个类,该类对 System.Web.HttpRequestBase 类进行了扩展,在其中添加了确定 HTTP 请求是否为 AJAX 请求的功能。
     5     public static class AjaxRequestExtensions
     6     {
     7         // 摘要: 
     8         //     确定指定的 HTTP 请求是否为 AJAX 请求。
     9         //
    10         // 参数: 
    11         //   request:
    12         //     HTTP 请求。
    13         //
    14         // 返回结果: 
    15         //     如果指定的 HTTP 请求是 AJAX 请求,则为 true;否则为 false。
    16         //
    17         // 异常: 
    18         //   System.ArgumentNullException:
    19         //     request 参数为 null(在 Visual Basic 中为 Nothing)。
    20         public static bool IsAjaxRequest(this HttpRequestBase request);
    21     }
    22 }

    但是呢,这只能在 Action 内部调用了,使得 Action 变得臃肿,需要在 Action 内部分别返回是否是 ajax 请求的结果。

    如果能像打上 HttpGet、HttpPost 之类标签的办法来做就更好了。

    查阅资料得出,要这样做,需要我们自己写一个 Attribute,并且这个 Attribute 继承自抽象类 ActionMethodSelectorAttribute。

    那么就好办了。代码如下:

     1 namespace System.Web.Mvc
     2 {
     3     /// <summary>
     4     /// 表示一个特性,该特性用于限制操作方法,以便该方法仅处理 AJAX 请求。
     5     /// </summary>
     6     [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
     7     public sealed class AjaxRequestAttribute : ActionMethodSelectorAttribute
     8     {
     9         /// <summary>
    10         /// 初始化 AjaxRequestAttribute 类的新实例。
    11         /// </summary>
    12         public AjaxRequestAttribute()
    13             : this(true)
    14         {
    15         }
    16 
    17         /// <summary>
    18         /// 初始化 AjaxRequestAttribute 类的新实例。
    19         /// </summary>
    20         /// <param name="isAjaxRequest">限制操作方法是否是 AJAX 请求。</param>
    21         public AjaxRequestAttribute(bool isAjaxRequest)
    22         {
    23             IsAjaxRequest = isAjaxRequest;
    24         }
    25 
    26         /// <summary>
    27         /// 指示操作方法是否是 AJAX 请求。
    28         /// </summary>
    29         public bool IsAjaxRequest
    30         {
    31             get;
    32             private set;
    33         }
    34 
    35         /// <summary>
    36         /// 确定操作方法 AJAX 请求对指定的控制器上下文是否有效。
    37         /// </summary>
    38         /// <param name="controllerContext">控制器上下文。</param>
    39         /// <param name="methodInfo">有关操作方法的信息。</param>
    40         /// <returns>如果操作方法请求对指定的控制器上下文有效,则为 true;否则为 false。</returns>
    41         public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    42         {
    43             if (controllerContext == null)
    44             {
    45                 throw new ArgumentNullException("controllerContext");
    46             }
    47 
    48             bool isAjaxRequest = controllerContext.HttpContext.Request.IsAjaxRequest();
    49             return IsAjaxRequest == isAjaxRequest;
    50         }
    51     }
    52 }

    PS:实际运用不建议命名空间这样做(与系统类库或泛用第三方类库重合),假如某一天 MVC 团队真的加了这么一个 Attribute,那么就会编译错误了。这里仅作演示,因为暂时想不到一个好的命名空间。-_-|||

    那么,只要打上该 Attribute 的 Action,如果构造函数参数为 true 或调用无参构造函数的话,则请求必须为 AJAX 请求。如果构造函数参数为 false,则不能是 AJAX 请求。

    如果上述条件不成立,则返回 404 Not Found。

  • 相关阅读:
    XVIII Open Cup named after E.V. Pankratiev Stage 5: Eastern Grand Prix
    XX Russia Team Open, High School Programming Contest St Petersburg, Barnaul, Tbilisi, Almaty, Kremenchug, November 30, 2019
    2019-2020 ICPC, NERC, Northern Eurasia Finals
    The 2019 China Collegiate Programming Contest Harbin Site
    Southeastern European Regional Programming Contest 2019
    2019-2020 ICPC, Asia Jakarta Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)
    2019-2020 Saint-Petersburg Open High School Programming Contest (SpbKOSHP 19)
    hdu6354 Everything Has Changed (圆的相交弧长)
    hdu6341 Problem J. Let Sudoku Rotate (dfs)
    hdu6333 Problem B. Harvest of Apples(组合数+莫队)
  • 原文地址:https://www.cnblogs.com/h82258652/p/3939365.html
Copyright © 2011-2022 走看看