自定义动作选择器在MVC和Web API中的应用

在ASP.NETMVCWeb API框架中,动作选择器起着至关重要的作用。它负责根据HTTP请求选择相应的动作(Action)来处理请求。默认情况下,框架会根据HTTP方法、路由模板中的占位符以及控制器上动作的参数来选择动作。但是,在某些情况下,可能需要根据特定的逻辑来自定义动作选择的过程。本文将介绍如何在MVC和Web API中实现自定义动作选择器,并解释其与动作过滤器的区别。

MVC中实现自定义动作选择器

MVC中,可以通过继承ActionMethodSelectorAttribute类并重写IsValidForRequest方法来实现自定义动作选择器。下面是一个简单的示例,展示了如何仅接受AJAX请求、HTTPS连接以及特定语言(例如英语)的请求。

public class ActionDecorationAttribute : ActionMethodSelectorAttribute { public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { // 检查是否为AJAX请求 if (!controllerContext.HttpContext.Request.IsAjaxRequest()) throw new Exception("只接受AJAX调用"); // 检查是否为HTTPS请求 if (!controllerContext.HttpContext.Request.IsSecureConnection) throw new Exception("只支持HTTPS"); // 检查用户语言是否为英语 if (controllerContext.HttpContext.Request.UserLanguages[0] != "en-US") throw new Exception("仅限英语用户"); return true; } }

在上面的代码中,定义了一个名为ActionDecorationAttribute的自定义动作选择器。它通过检查请求的类型、安全性和用户语言来决定是否接受该请求。如果请求不符合条件,将抛出异常。接下来,需要将这个自定义动作选择器应用到控制器的动作上。

public class HomeController : Controller { [ActionDecoration] public ActionResult Index() { return new EmptyResult(); } }

现在,当请求Index动作时,会在执行动作之前触发ActionDecorationAttribute类中的验证方法。

Web API中实现自定义动作选择器

Web API中,可以通过继承ApiControllerActionSelector类来实现自定义动作选择器。下面是一个简单的示例,展示了如何根据请求类型选择动作。

public class ApiActionSelector : ApiControllerActionSelector { public override HttpActionDescriptor SelectAction(HttpControllerContext context) { HttpMessageContent requestContent = new HttpMessageContent(context.Request); var actionMethod = context.ControllerDescriptor.ControllerType .GetMethods(BindingFlags.Instance | BindingFlags.Public) .FirstOrDefault(); if (actionMethod != null) { return new ReflectedHttpActionDescriptor(context.ControllerDescriptor, actionMethod); } return base.SelectAction(context); } }

在上面的代码中,定义了一个名为ApiActionSelector的自定义动作选择器。它通过检查请求的内容来决定选择哪个动作。在实际应用中,可以在这个基础上实现更复杂的逻辑。接下来,需要在WebApiConfig类中配置自定义动作选择器。

public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // 配置自定义动作选择器 config.Services.Replace(typeof(IHttpActionSelector), new ApiActionSelector()); } }

现在,当调用以下动作时:

public class testController : ApiController { [System.Web.Http.ActionName("action1")] public void Get() { } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485