Как отобразить строку запроса? Action = Blah к действию в маршруте MVC3? - PullRequest
1 голос
/ 23 октября 2011

Я хотел бы использовать маршрут с действием в строке запроса

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

, чтобы я мог использовать относительные URL на стороне клиента

Есть липростой способ добиться этого?

Ответы [ 3 ]

1 голос
/ 23 октября 2011

Решение, которое предоставил @Darin, достаточно хорошее и полезное, но есть проблема с action s, который не предоставляется 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;
    }

} 
1 голос
/ 23 октября 2011

Вы можете взглянуть на следующую запись в блоге , которая иллюстрирует одну технику, которая позволит вам достичь этого. Он использует пользовательский 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 должен всегда указываться, иначе вызывающий действие не будет знать, какое действие выполнить.

0 голосов
/ 11 сентября 2012

Я использую это решение:

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-адреса

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...