我知道我可以创建支持此网址的网址映射
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)
category / idex / catId / 1 / groupId / 2
ActionResult Index (catId String, String groupId)
新闻/明细/ newsId / 1 / groupId / 2 / 选项 / 3
ActionResult Index (newsid String, String groupId, String optionId)
答案 0 :(得分:0)
我认为你不能这样做,但你可以这样做:
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
答案 1 :(得分:0)
我做到了!!
使用自定义值提供程序!
我更改了值对参数
的格式来自 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());
}