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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM