我想创建使用Id值路由到控制器操作的动态URL。我使用catch-all参数
创建了以下路由routes.MapRoute(
"RouteName",
"{id}/{*Url}",
new { controller = "Controller", action = "Action", id = "" }
);
这可以按预期工作,并允许我使用以下网址:
“http://website.com/1/fake/url/path”(1是传递给action方法的id)
有没有人知道以这种方式实现它的方法而不创建我自己的http模块?:
“http://website.com/fake/url/path/1”
谢谢 - 马克
答案 0 :(得分:1)
无论如何,这对我来说真的很难。
考虑以下路线:
routes.MapRoute("Default", "{*token}",
new { controller = "Home", action = "Index", token = 0 });
您的控制器和支持类将是这样的:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index([ModelBinder(typeof(IndexReqquestBinder))] IndexRequest request)
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = String.Format("We're looking at ID: {0}", request.ID);
return View();
}
}
public class IndexRequest
{
public Int32 ID { get; set; }
public IndexRequest(Int32 id)
{
this.ID = id;
}
}
public class IndexReqquestBinder : IModelBinder
{
public ModelBinderResult BindModel(ModelBindingContext bindingContext)
{
if ( null != bindingContext.RouteData.Values["token"] ) {
foreach ( String v in bindingContext.RouteData.Values["token"].ToString().Split('/') ) {
Int32 id = 0;
if ( Int32.TryParse(v, out id) ) {
return new ModelBinderResult(new IndexRequest(id));
}
}
}
return new ModelBinderResult(new IndexRequest(0));
}
}
答案 1 :(得分:1)
路由重定向基于路由表中的路由条目。它必须系统化。例如,如果您在{controller} / {action} / {id}(默认为mvc)之后将路由设置为“customurl / id”,那么当您在url框中输入“customurl”时,它将把它作为默认路由而不是页面发现异常会发生。因此,如果您想使用自定义路由,请先删除默认路由。我喜欢这样做。
RouteCollection routes = RouteTable.Routes;
if (routes["rname"] != null)
{
RouteTable.Routes.Remove(routes["rname"]);
}
routes.Remove(routes["Default"]);
routes.MapRoute(
name: "newname",
url: url + "/{customId}",
defaults: new { controller = "Search", action = "Index", customId = UrlParameter.Optional }
);
//default route value
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
答案 2 :(得分:0)
我建议覆盖DefaultControllerFactory
> public class CustomControllerFactory : DefaultControllerFactory
> {
> public override IController
> CreateController(System.Web.Routing.RequestContext
> requestContext, string controllerName)
> {
> try
> {
> return base.CreateController(requestContext,
> controllerName);
> }
> catch (Exception exception)
> {
> // collect route data
> string id = (string)requestContext.RouteData.Values["id"];
> string action = (string)requestContext.RouteData.Values["action"];
> // set full path as routing "page" parameter
> VirtualPathData path = requestContext.RouteData.Route.GetVirtualPath(requestContext,
> requestContext.RouteData.Values);
> requestContext.RouteData.Values["id"]
> = path.VirtualPath; // or anything you need
> // use controller page by default
> controllerName = "MyController";
> // set basuc routing data
> requestContext.RouteData.Values["controller"]
> = controllerName;
> requestContext.RouteData.Values["action"]
> = "index";
> // call base method to create controller
> return base.CreateController(requestContext,
> controllerName);
> }
> }
>}
而不仅仅是将其注册为global.asax.cs文件中的默认控制器工厂
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new MyNameSpace.CustomControllerFactory ());
RegisterRoutes(RouteTable.Routes); // this already exists by default
}