如何映射querystring?Action = Blah在MVC3路由中的动作?

时间:2011-10-23 15:46:45

标签: asp.net-mvc-3

我想在查询字符串中使用带有操作的路由

http://server/path/controller?action=save

所以我可以在客户端使用相对网址

有没有简单的方法来实现这一目标?

3 个答案:

答案 0 :(得分:1)

您可以查看following blog post,其中介绍了一种可以实现此目的的技术。它使用自定义ActionNameSelectorAttribute

如果你真的想在全球范围内这样做,另一种可能性就是写一个自定义路线,如下所示:

public class MyRoute : Route
{
    public MyRoute(string url, object defaults)
        : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
    { }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var rd = base.GetRouteData(httpContext);
        var action = httpContext.Request["action"];
        if (rd != null && !string.IsNullOrEmpty(action))
        {
            rd.Values["action"] = action;
        }
        return rd;
    }
}

然后注册:

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

    routes.Add(
        "Default", 
        new MyRoute(
            "{controller}/{id}", 
            new { controller = "Home", id = UrlParameter.Optional }
        )
    );
}

现在,当您请求/home?action=about时,将会执行About控制器的Home操作。显然,如果从请求中省略action参数,您将获得异常,因为必须始终指定路由的action标记,或者操作调用程序不知道要执行哪个操作。

答案 1 :(得分:1)

@Darin提供的解决方案很好且非常有用,但action未提供Html.ActionLink的问题,例如Index操作会导致错误像这样:

  

RouteData必须包含名为“action”且非空的项目   字符串值。

所以你必须将MyRoute更改为这个:

public class MyRoute : Route {

    public MyRoute(string url, object defaults)
        : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler()) { }

    public override RouteData GetRouteData(HttpContextBase httpContext) {

        var routeData = base.GetRouteData(httpContext);
        var action = httpContext.Request["action"];
        if (routeData != null && !string.IsNullOrEmpty(action)) {
            routeData .Values["action"] = action;
        } 

        // you have to add something like this:
        else {      
            routeData .Values["action"] = "Index";
        }
        return routeData;
    }

} 

答案 2 :(得分:0)

我使用这个解决方案:

public override RouteData GetRouteData(HttpContextBase httpContext) {
    var routeData = base.GetRouteData(httpContext);
    string action = httpContext.Request.QueryString["Action"];
    routeData.Values["action"] = String.IsNullOrEmpty(action) ? "Index" : action;
    return routeData;
}//method

但是要完成这项工作,你还必须实现GetVirtualPath():

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) {
    string url = "up to you";
    var data = new VirtualPathData(this, url);
    // also consider DataTokens ...
    return data;
}//method

这确保了诸如ActionLink()之类的帮助程序将生成正确的URL