MVC url路由键值对参数

发布于 2024-12-03 19:13:33 字数 1048 浏览 1 评论 0原文

我知道我可以创建一个支持此url

user / idex / userId / 1 / categoryId / abc

ActionResult Index (String userId, String categoryID)

的url映射我想知道是否可以推广此机制并编写一个映射,该映射可以支持作为键/值对传递的所有基于 url 的参数。

控制器 / 操作 / *key1 /值1/ 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)

新闻 / 详情 / 新闻 ID / 1 / 群组 ID / 2 / 选项 / 3

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

I know that I can create a url mapping that supports this url

user / idex / userId / 1 / categoryId / abc

ActionResult Index (String userId, String categoryID)

What I wonder is whether it is possible to generalize this mechanism and write a single mapping that can support all url-based parameters passed as key / value pairs.

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

With a single mapping I need to supported for example all these 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)

category / idex / catId / 1 / groupId / 2

ActionResult Index (catId String, String groupId)

news / detail / newsId / 1 / groupId / 2 / option / 3

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盗梦空间 2024-12-10 19:13:33

我不认为你可以这样做,但你可以这样做:

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)

给出 news/detail/1/2类别/索引/1/2

I don't think you can do it that way, but you could do:

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
);

But then all the actions you want to use this for, there methods should be defined as

ActionResult ActionName (string id, string groupid)

giving news/detail/1/2 and category/index/1/2

幼儿园老大 2024-12-10 19:13:33

我做到了!!

使用自定义值提供者!

我将值对参数的格式

key1 / value1 / key2 / value2

更改为更清晰的 key1=value1;key2=value2

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());
}

I did it!!

using a custom value provider!

I changed the format of the value pairs parameter

from key1 / value1 / key2 / value2

to a more clear key1=value1;key2=value2

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;
            }
        }
    }
}

Sure, it can be enanced using regex.

Then, in the 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());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文