Asp.net MVC 應用程序中經常使用ajax操作,一般都是一些action。我們來實現個特性標記當前某個action只支持處理ajax的http請求。 下面直接看代碼
/// <summary> /// AjaxOnlyAttribute /// </summary> public class AjaxOnlyAttribute : ActionFilterAttribute { /// <summary> /// Called by the ASP.NET MVC framework before the action method executes. /// </summary> /// <param name="filterContext">The filter context.</param> public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.Result = new HttpNotFoundResult(); } base.OnActionExecuting(filterContext); } }
這里讓它返回一個特別的HttpNotFoundResult, 以確保代碼可讀性:
/// <summary> /// HttpNotFoundResult /// </summary> public class HttpNotFoundResult : ActionResult { /// <summary> /// Enables processing of the result of an action method by a custom type that inherits from the <see cref="T:System.Web.Mvc.ActionResult"/> class. /// </summary> /// <param name="context">The context in which the result is executed. The context information includes the controller, HTTP content, request context, and route data.</param> public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("Context"); } context.HttpContext.Response.StatusCode = 401; } }
在Action標記像這樣:
[AjaxOnly] public ActionResult LogOff() { FormsAuthentication.SignOut(); return RedirectToAction("Index", "Home"); }
如何工作的看Unit Test,分別包括了Ajax請求與非Ajax請求的場景.
[TestMethod] public void Test_AjaxOnlyAttributeWithAjaxRequest() { //arrange var header = new System.Collections.Specialized.NameValueCollection(); header.Add("X-Requested-With", "XMLHttpRequest"); var mockRequest = new Mock<HttpRequestBase>(); mockRequest.SetupGet(http => http.Headers).Returns(header); var mockFiltercontext = new Mock<ActionExecutingContext>(); mockFiltercontext.SetupGet(fc => fc.HttpContext.Request).Returns(mockRequest.Object); //act var ajaxAttribute = new AjaxOnlyAttribute(); var filterContext = mockFiltercontext.Object; ajaxAttribute.OnActionExecuting(filterContext); //verify mockRequest.VerifyAll(); //assert Assert.IsTrue(filterContext.HttpContext.Request.IsAjaxRequest()); var httpNotFoundResult = filterContext.Result as Mvc3App.Extention.Attribute.HttpNotFoundResult; Assert.IsNull(httpNotFoundResult); } [TestMethod] public void Test_AjaxOnlyAttributeWithNonAjaxRequest() { //arrange var header = new System.Collections.Specialized.NameValueCollection(); var mockRequest = new Mock<HttpRequestBase>(); mockRequest.SetupGet(http => http.Headers).Returns(header); var mockFiltercontext = new Mock<ActionExecutingContext>(); mockFiltercontext.SetupGet(fc => fc.HttpContext.Request).Returns(mockRequest.Object); var controllerContext = new ControllerContext { RequestContext = new RequestContext(new MockHttpContext(), new RouteData()), HttpContext = new MockHttpContext() }; //act var ajaxAttribute = new AjaxOnlyAttribute(); var filterContext = mockFiltercontext.Object; ajaxAttribute.OnActionExecuting(filterContext); //verify mockRequest.VerifyAll(); //assert Assert.IsFalse(filterContext.HttpContext.Request.IsAjaxRequest()); var httpNotFoundResult = filterContext.Result as Mvc3App.Extention.Attribute.HttpNotFoundResult; Assert.IsNotNull(httpNotFoundResult); httpNotFoundResult.ExecuteResult(controllerContext); Assert.AreEqual(controllerContext.HttpContext.Response.StatusCode, 401); }
MockHttpContext是一個用於Unit Test的類型,由於篇幅有限,這里不講了。
希望對您Web開發有幫助。
您可能感興趣文章:
Asp.net MVC3擴展之Ajax異常處理特性
作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
該文章也同時發布在我的獨立博客中-Petter Liu Blog。