【问题标题】:How to append a prefix to action name according to a particular route如何根据特定路由将前缀附加到操作名称
【发布时间】:2013-04-05 19:08:42
【问题描述】:

我正在使用 asp.net mvc 4 和 web api。我的路线是这样的:

/api/{controller}/jqGrid/{action}/{id}

例如,如果路线是:

/api/User/jqGrid/List

我希望它会路由到用户控制器的动作名称“jqGrid_List”。

我怎样才能做到这一点?

【问题讨论】:

    标签: asp.net asp.net-web-api


    【解决方案1】:

    嗯,我不知道是否可以回答我自己的问题。我找到了解决办法。

    首先,我需要添加一个 JqGridControllerConfiguration 属性,以将应用于控制器的默认操作选择器替换为我的。

    [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;
        }
    }
    

    JqGridControllerConfiguration 的代码如下:

    public class JqGridControllerConfiguration : Attribute, IControllerConfiguration
    {
        public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
        {
            controllerSettings.Services.Replace(typeof(IHttpActionSelector), new JqGridActionSelector());
        }
    }
    

    在 JqGridActionSelector 中,如果请求 URL 中存在“jqGrid/”,则修改“action”。

    public class JqGridActionSelector : ApiControllerActionSelector
    {
        public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
        {
            Uri url = controllerContext.Request.RequestUri;
            if (url.Segments.Any(s => string.Compare(s, "jqGrid/", true) == 0))
            {
                controllerContext.RouteData.Values["action"] = "jqGrid_" + controllerContext.RouteData.Values["action"].ToString();
            }
    
            return base.SelectAction(controllerContext);
        }
    }
    

    【讨论】:

    • 这真是矫枉过正,为什么不在动作上使用 ActionName("List") 属性?
    • 我想在控制器中有两个“List”动作,一个用于常规调用(/User/List),一个用于jqGrid调用(/User/jqGrid/List)。
    【解决方案2】:

    不确定您为什么要这样做。但是您仍然可以在您的用户控制器中创建一个“jqGrid_List”操作并为其设置一个 ActionName,它会起作用。

    用户控制器

        [HttpGet, ActionName("List")]
        public string jqGrid_List()
        {
            return "WORKS";
        }
    

    您的路线

    routeTemplate: "api/{controller}/jqGrid/{action}/{id}"
    

    【讨论】:

    • 感谢您的建议。我将在控制器中有两个 List 动作,一个“/User/List”将调用常规 List 动作,一个“/User/jqGrid/List”将调用 jqGrid_List 方法。我可以制作不同的 Url,例如“/User/jqGrid_List”,但我认为“/User/jqGrid/List”可能更友好。
    • 将它们命名为 2 个单独的函数名称。你可以给他们两个 ActionName “List”。然后在我在上面的答案中建议的路线之后创建另一条路线,并删除“jqGrid”:“api/{controller}/{action}/{id}”
    猜你喜欢
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 2014-09-29
    • 2018-11-10
    • 1970-01-01
    • 2020-06-24
    • 2016-06-19
    相关资源
    最近更新 更多