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。