Asp.net mvc ASP MVC-使用参数名访问控制器/操作

Asp.net mvc ASP MVC-使用参数名访问控制器/操作,asp.net-mvc,asp.net-mvc-routing,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参数工作?默认情况下,内置路由忽略查询字符串值(它不会将它们添加到Route

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

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

www.domain.com/area1/mycontroller/MyAction

当我使用区域作为参数时,它对我有效,但当我使用控制器和操作作为查询参数时,它失败了。是否有办法使其作为Url参数工作?

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

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);
    }
}
用法 我还没有测试过这个,所以它可能需要一些调整才能正常工作,但这就是你可以做到的


但是请注意,这不利于SEO,您还需要添加额外的代码来处理参数,而不是
控制器
操作
区域
(例如
id
)。您可以将要匹配的值传递到路由构造函数中,然后使用不同的参数注册
QueryStringRoute
类以克服此问题。

默认情况下,内置路由忽略查询字符串值(它不会将它们添加到
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);
    }
}
用法 我还没有测试过这个,所以它可能需要一些调整才能正常工作,但这就是你可以做到的


但是请注意,这不利于SEO,您还需要添加额外的代码来处理参数,而不是
控制器
操作
区域
(例如
id
)。您可以将要匹配的值传递到路由构造函数中,然后使用不同的参数注册
QueryStringRoute
类,以克服此问题。

您指的是使用带有/而不是查询参数的URL(请确保在URL中不使用控制器名称的控制器部分)?类似www.domain.com/area1/my/MyAction的内容我想从url本身删除控制器和操作,并将其添加为查询参数@MadsTaanquist的可能重复项否我不想改变路由的工作方式,我希望它是一样的,但通过查询字符串和“域/控制器/操作”参数来访问它。。。我希望它如下:'域?参数',这样参数将告诉控制器和操作您可以在RouteConfig中显示代码吗?您指的是使用带有/而不是查询参数的URL(请确保在URL中控制器名称中不包含控制器部分)?类似www.domain.com/area1/my/MyAction的内容我想从url本身删除控制器和操作,并将其添加为查询参数@MadsTaanquist的可能重复项否我不想改变路由的工作方式,我希望它是一样的,但通过查询字符串和“域/控制器/操作”参数来访问它。。。我希望它如下:'域?参数',这样参数将告诉控制器和操作您能在您的RouteConfig中显示代码吗?我明白了。。谢谢但我想知道“内置路由忽略查询字符串值”为什么在添加“区域”参数时有效,而在添加控制器或操作作为参数时无效?因为使用
数据令牌
(元数据)而不是
(路由值)才能起作用。换句话说,它们与非区域路由不同,因此它们的实现方式也不同。显然,这些差异之一是考虑查询字符串值(但我似乎找不到源发生的地方)。如果您只想使用查询字符串值进行导航,则必须使用类似于我上面提供的自定义路由,内置路由扩展无法做到这一点。我明白了。。谢谢但我想知道“内置路由忽略查询字符串值”为什么在添加“区域”参数时有效,而在添加控制器或操作作为参数时无效?因为使用
数据令牌
(元数据)而不是
(路由值)才能起作用。换句话说,它们与非区域路由不同,因此它们的实现方式也不同。显然,这些差异之一是考虑查询字符串值(但我似乎找不到源发生的地方)。如果只想使用查询字符串值进行导航,则必须使用类似于我上面提供的自定义路由,内置路由扩展无法做到这一点。