在asp.net web api中动态修改action的名字
在路由设置中,我的路由是这样的:
/api/{controller}/jqGrid/{action}/{id}
对于如下URL,默认情况下执行的是UserController类的List方法:
/api/User/jqGrid/List
而我希望凡是url中含有jqGrid的路由,都执行“jqGrid_{action}”名字的方法,即 jqGrid_List 方法。经过数天地折磨,终于解决了。上代码(这里照搬我在stackoverflow上的提问和我自己的回答了,英语高手欢迎指出文中不地道的英语,谢谢):
First of all, I need to add a JqGridControllerConfiguration attribute to replace the default action selector applied to the controller with my one.
[JqGridControllerConfiguration]
public class UserController : ApiController
{
// GET: /api/User/jqGrid/List
[HttpGet]
public JqGridModel<User> jqGrid_List()
{
JqGridModel<User> result = new JqGridModel<User>();
result.rows = Get();
return result;
}
}
Here's the code of JqGridControllerConfiguration:
1 public class JqGridControllerConfiguration : Attribute, IControllerConfiguration
2 {
3 public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
4 {
5 controllerSettings.Services.Replace(typeof(IHttpActionSelector), new JqGridActionSelector());
6 }
7 }
in JqGridActionSelector, the "action" is modified if a "jqGrid/" exists in the request URL.
1 public class JqGridActionSelector : ApiControllerActionSelector
2 {
3 public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
4 {
5 Uri url = controllerContext.Request.RequestUri;
6 if (url.Segments.Any(s => string.Compare(s, "jqGrid/", true) == 0))
7 {
8 controllerContext.RouteData.Values["action"] = "jqGrid_" + controllerContext.RouteData.Values["action"].ToString();
9 }
10
11 return base.SelectAction(controllerContext);
12 }
13 }
理解的越多,需要记忆的就越少