ASP MVC - 使用参数名称的Access Controller / Action

时间:2016-07-09 18:26:45

标签: asp.net-mvc asp.net-mvc-routing

我正在使用ASP MVC4,我想知道我是否可以打开如下特定页面:

www.domain.com?Area=area1&controller=myController&Action=MyAction

而不是

www.domain.com/area1/mycontroller/MyAction

当我使用区域作为参数时,它对我有用,但当我使用控制器和动作作为查询参数时,它也会失败。有没有办法让它作为Url参数工作?

1 个答案:

答案 0 :(得分:2)

默认情况下,内置路由会忽略查询字符串值(它不会将它们添加到RouteData.Values字典中)。但是,没有理由不扩展路由来考虑它们。

public class QueryStringRoute : RouteBase
{
    public RouteData GetRouteData(HttpContextBase httpContext)
    {
        var path = httpContext.Request.Path;

        if (!string.IsNullOrEmpty(path))
        {
            // Don't handle URLs that have a path /controller/action
            return null;
        }

        var queryString = httpContext.Request.QueryString;

        if (!queryString.HasKeys())
        {
            // Don't handle the route if there is no query string.
            return null;
        }

        if (!queryString.AllKeys.Contains("controller") && !queryString.AllKeys.Contains("action"))
        {
            // Don't handle the case where controller and action are missing.
            return null;
        }

        var controller = queryString["controller"];
        var action = queryString["action"];
        var area = queryString["area"];

        var routeData = new RouteData(this, new MvcRouteHandler());

        routeData.Values["controller"] = controller;
        routeData.Values["action"] = action;
        routeData.DataTokens["area"] = area;

        return routeData;
    }

    public VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        // NOTE: MVC automatically tacks unrecognized route values onto
        // the query string. So, it is sufficient to just call your 
        // ActionLink normally and returning an empty string for the URL
        // will send it to mysite.com/?controller=foo&action=bar
        return new VirtualPathData(this, string.Empty);
    }
}

用法

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Add the query string route
        routes.Add(new new QueryStringRoute());
    }
}

我还没有对此进行过测试,所以可能需要进行一些调整才能使其正常工作,但这就是你可以做到的。

请注意,这对SEO不利,您还需要添加其他代码来处理controlleractionarea以外的参数(例如{{1} }})。您可以传递值以匹配路径构造函数,然后使用不同参数注册id类以克服此问题。