Параметры пар ключей ключ маршрутизации URL MVC - PullRequest
0 голосов
/ 08 сентября 2011

Я знаю, что могу создать отображение URL, которое поддерживает этот URL

user / idex / userId / 1 / categoryId / abc

ActionResult Index (String userId, String categoryID)

Что меня интересует, так это то, можно ли обобщить этот механизм и написать одно отображение, которое может поддерживать все основанные на URL параметры, передаваемые как пары ключ / значение.

controller / action / * key1 / value1 / key2 / value2 .... *

При одном отображении мне нужно, например, поддерживать всеЭти URL

user / idex / userId / 1 / categoryId / abc

ActionResult Index (String userId, String categoryID)

category / idex / catId / 1 / groupId /2

ActionResult Index (catId String, String groupId)

категория / idex / catId / 1 / groupId / 2

ActionResult Index (catId String, String groupId)

news / detail / newsId / 1 / идентификатор группы / 2 / опция / 3

ActionResult Index (newsid String, String groupId, String optionId)

Ответы [ 2 ]

0 голосов
/ 08 сентября 2011

Я сделал это !!

с использованием провайдера пользовательских значений!

Я изменил формат параметра пары значений

из ключ1 / значение1 / ключ2 / значение2

до более понятного ключ1 = значение1; ключ2 = значение2

public class KeyValuePairValueProviderFactory : ValueProviderFactory {
    public override IValueProvider GetValueProvider(ControllerContext controllerContext) {
        return new KeyValuePairValueProvider(controllerContext.HttpContext.Request.Path);
    }
    private class KeyValuePairValueProvider : IValueProvider {
        private readonly Dictionary<String,String> _valuesDictionary = new Dictionary<String,String>();

        public bool ContainsPrefix(string prefix) {
            return true;
        }

        public KeyValuePairValueProvider(String rawUrl) {
            // The url have to be in this format
            // controller/key=value
            // controller/key=value/
            // controller/key=value?op=1
            // controller/key=value/?op=1
            // controller/action/key=value
            // controller/action/key=value?op=1
            // controller/action/key=value/?op=1
            // controller/action/key=value;key=value
            // controller/action/key=value;key=value?op=1
            // controller/action/key=value;key=value/?op=1
            String parameters = "";

            // removing the querystring
            if(rawUrl.Contains("?")){
                // i split on the ? and take the first part
                rawUrl = rawUrl.Split('?')[0];
            }


            // controller/key=value
            // controller/action/key=value
            // controller/action/key=value/
            // controller/action/key=value;key=value


            // check if the url without the querystring contains a = simbol
            // if yes I proceed into extract parameters
            if(rawUrl.Contains("=")){

                // removing last slash
                if (rawUrl.LastIndexOf('/')+1 == rawUrl.Length) {
                    rawUrl = rawUrl.Remove(rawUrl.LastIndexOf('/'));
                }


                int startIndex = rawUrl.LastIndexOf("/")+1;
                int endIndex = rawUrl.Length;
                int lenght = endIndex-startIndex;
                parameters = rawUrl.Substring(startIndex,lenght);
                String[] pairs = parameters.Split(';');
                foreach (String pair in pairs) { 
                    String key = pair.Split('=')[0];
                    String value = pair.Split('=')[1];
                    _valuesDictionary.Add(key, value);
                }
            }
        }

        public ValueProviderResult GetValue(string key) {
            if (_valuesDictionary.ContainsKey(key)) {
                return new ValueProviderResult(
                    _valuesDictionary[key]
                    , _valuesDictionary[key]
                    , CultureInfo.CurrentUICulture);
            } else {
                return null;
            }
        }
    }
}

Конечно, это можно улучшить с помощью регулярных выражений.

Тогда в global.asax

public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{*catchall}", // URL with parameters
    new { controller = "Home", action = "Index" } // Parameter defaults
    );
}

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    ValueProviderFactories.Factories.Add(new KeyValuePairValueProviderFactory());
}
0 голосов
/ 08 сентября 2011

Я не думаю, что вы можете сделать это таким образом, но вы могли бы сделать:

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

Но тогда все действия, для которых вы хотите использовать это, методы должны быть определены как

ActionResult ActionName (string id, string groupid)

предоставление новости / подробности / 1/2 и категория / индекс / 1/2

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