использование ограничений маршрута mvc, чтобы URL можно было сопоставить только одному из трех возможных параметров - PullRequest
16 голосов
/ 27 февраля 2012

Вот мой маршрут:

routes.MapRoute(null, "myaccount/monitor/{category}", // Matches
                new { controller = "MyAccount", action = "Monitor", category = (string)null }
);

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

Ответы [ 3 ]

26 голосов
/ 27 февраля 2012

Вы можете использовать UrlParameter.Optional для разрешения нуля, а также использовать параметр constraints метода MapRoute ..

 routes.MapRoute(null,
                      "myaccount/monitor/{category}", // Matches
                      new { controller = "MyAccount", action = "Monitor", category = UrlParameter.Optional  },
                      new { category = "overview|projection|history"}
            );
3 голосов
/ 28 февраля 2012

Встроенный Regex Gaby будет работать. Другой способ сделать это - определить пользовательский IRouteConstraint:

public class FromValuesListConstraint : IRouteConstraint
{
    private List<string> _values;

    public FromValuesListConstraint(params string[] values)
    {
        this._values = values.Select(x => x.ToLower()).ToList();
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        string value = values[parameterName].ToString();

        if (string.IsNullOrWhiteSpace(value))
        {
            return _values.Contains(string.Empty);
        }

        return _values.Contains(value.ToLower());
    }
}

Затем передайте экземпляр ограничения в ваш вызов MapRoute:

routes.MapRoute(null,
    "myaccount/monitor/{category}", // Matches
new { controller = "MyAccount", action = "Monitor", category = UrlParameter.Optional  },
new { category = new FromValuesListConstraint ("overview", "projection", "history", string.Empty) }
        );
0 голосов
/ 27 февраля 2012

Я думаю, вам, возможно, придется использовать отдельные маршруты:

routes.MapRoute("Monitor",
                      "myaccount/monitor", // Matches
                      new { controller = "MyAccount", action = "Monitor" }
            );

routes.MapRoute("MonitorHistory",
                      "myaccount/monitor/history", // Matches
                      new { controller = "MyAccount", action = "Monitor", category = "history" }
            );

routes.MapRoute("MonitorOverview",
                      "myaccount/monitor/overview", // Matches
                      new { controller = "MyAccount", action = "Monitor", category = "overview" }
            );

routes.MapRoute("MonitorProjection",
                      "myaccount/monitor/projection", // Matches
                      new { controller = "MyAccount", action = "Monitor", category = "projection" }
            );

Альтернативно , вы можете захотеть сделать что-то вроде:

routes.MapRoute("MonitorGlobal",
                      "myaccount/monitor/{category}", // Matches
                      new { controller = "MyAccount", action = "Monitor", category = string.Empty }
            );

А потом в вашем контроллере:

public ActionResult Monitor(string category)
{
    switch (category)
    {
        case string.Empty:
            // do something
            break;

        case "overview":
            // do something
            break;

        // so on and so forth

        default:
            // no match, handle accordingly
            break;
    }
}
...