Как вы переопределяете значения таблицы маршрутов по умолчанию, используя Html.ActionLink? - PullRequest
3 голосов
/ 01 февраля 2011

Значения маршрута Global.asax

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional, filterDate = DateTime.Now.AddDays(-1), filterLevel = "INFO" } // Parameter defaults
        );

Вот моя actionlink

        @Html.ActionLink(item.MachineName, "Machine", new { id = item.MachineName, filterLevel = "hello" }, null)

Когда в actionlink указан уровень фильтра, он генерирует URL-адрес следующим образом:

http://localhost:1781/LoggingDashboard/log/level/VERBOSE

На той же странице, на которой я сейчас нахожусь.Если я изменю actionlink для использования свойства, отличного от того, которое имеет значение по умолчанию в таблице маршрутов (да, если я использую filterDate, оно тоже портится), оно генерирует такую ​​ссылку:

@Html.ActionLink(item.MachineName, "Machine", new { id = item.MachineName, foo = "bar" }, null)

http://localhost:1781/LoggingDashboard/log/Machine/C0UPSMON1?foo=bar

Это поведение правильно?Должен ли я быть в состоянии переопределить значения по умолчанию, установленные в таблице маршрутов?Я подтвердил, что если я удаляю defaultLevel по умолчанию из таблицы маршрутов, это будет работать так, как я ожидаю:

http://localhost:1781/LoggingDashboard/log/Machine/C0UPSMON1?filterLevel=VERBOSE

--- EDIT --- извините, вот действие

        public ActionResult Machine(string id, DateTime filterDate, string filterLevel)
        {
...
            var model = new LogListViewModel { LogEntries = logEntries };
            return View(model);
        }

Для награды я хочу знать, как переопределить значения «по умолчанию», которые указаны в маршрутах из global.asax.т.е. я хочу иметь возможность переопределить filterLevel и filterDate.

Ответы [ 4 ]

3 голосов
/ 13 февраля 2011

SLaks уже сказал, что, вероятно, лучший способ справиться с этой проблемой.Я не знаю, сработает ли это, но что произойдет, если вы поместите это выше существующего маршрута (так что теперь в вашем global.asax их будет два)?

        routes.MapRoute(
            "Filtered",
            "{controller}/{action}/{id}?filterLevel={filterLevel}&filterDate={filterDate}",
            new
                {
                    controller = "Home",
                    action = "Index",
                    id = UrlParameter.Optional,
                    filterDate = DateTime.Now.AddDays(-1),
                    filterLevel = "INFO"
                } 
            );

Кроме того, мне просто пришло в голову, что причина, по которой вам не нравится решение SLaks, заключается в том, что оно может быть повторяющимся.Поскольку у вас есть только один маршрут, эти параметры, вероятно, указывают на глобальную функциональность, а не на функциональную область действия.Вы можете исправить это, добавив значения в фильтр действий на каждом контроллере, или вы можете использовать собственный обработчик маршрута, чтобы применить это глобально.Любой из них позволит вам удалить поля filterLevel и filterDate из определения маршрута и при этом получить желаемую область.Тогда не должно возникнуть проблем с передачей параметров в строке запроса с помощью Html.ActionLink().

. Для этого с помощью обработчика маршрута измените определение маршрута на:

        routes.Add(
            new Route(
                    "{controller}/{action}/{id}", 
                    new RouteValueDictionary(new{ controller = "Home", action = "Index", id = UrlParameter.Optional}), 
                    new CustomRouteHandler()));

Ваша реализацияобработчик маршрута будет выглядеть примерно так:

public class CustomRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var routeValues =  requestContext.RouteData.Values;
        if(!routeValues.ContainsKey("filterLevel"))
        {
            routeValues.Add("filterLevel","INFO");
        }
        if(!routeValues.ContainsKey("filterDate"))
        {
            routeValues.Add("filterDate", DateTime.Now.AddDays(-1));
        }
        var mvcRouteHandler = new MvcRouteHandler(); 
        return (mvcRouteHandler as IRouteHandler).GetHttpHandler(requestContext);
    }
}
1 голос
/ 07 февраля 2011

Вы должны указать значение по умолчанию в вашем методе, например:

public ActionResult Machine(string id, DateTime? filterDate = null, string filterLevel = "INFO")
{
    filterDate = filterDate ?? DateTime.Now.AddDays(-1);  
    var model = new LogListViewModel { LogEntries = logEntries };
    return View(model);
}
1 голос
/ 13 февраля 2011

Если в шаблоне URL заданы значения по умолчанию , а не , их нельзя переопределить, поскольку они используются для определения выбора маршрута при сопоставлении маршрутов для генерации URL.

Позвольте привести пример. Предположим, у вас были следующие два маршрута.

routes.MapRoute(
            "Default1", // Route name
            "foo/{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional
            , filterLevel = "INFO" } // Parameter defaults
        );

routes.MapRoute(
            "Default2", // Route name
            "bar/{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional
            , filterLevel = "DEBUG" } // Parameter defaults
        );

Обратите внимание, что для "filterLevel" установлено значение по умолчанию, но в шаблоне URL отсутствует параметр "{filterLevel}".

Какой URL должен совпадать, когда вы делаете это?

@Html.ActionLink(item.MachineName, "Machine", 
new { id = item.MachineName, filterLevel = "RANDOM" }, null)

Если бы вы могли переопределить значение по умолчанию для filterLevel, то вы ожидаете, что оба маршрута будут совпадать. Но это не имеет смысла. В этом случае ни один из них не совпадает, потому что filterLevel отсутствует в шаблоне URL, и, следовательно, предоставленный filterLevel должен соответствовать значению по умолчанию. Таким образом, вы можете сделать это:

@Html.ActionLink(item.MachineName, "Machine", 
new { id = item.MachineName, filterLevel = "INFO" }, null)

//AND

@Html.ActionLink(item.MachineName, "Machine", 
new { id = item.MachineName, filterLevel = "DEBUG" }, null)

для генерации URL для первого и второго маршрута соответственно.

Из-за этой путаницы я всегда рекомендую всегда использовать именованные маршруты .

1 голос
/ 01 февраля 2011

Я думал, что значения по умолчанию всегда были для записей, определенных в URL, что вы не можете определить значение по умолчанию для исключения чего-либо, чего нет в основном URL, а все остальное передается в виде строки запроса.

Интересный вопрос.

HTH.

...