2008-11-17 2 views
3

Я хотел бы создать динамические URL-адреса, которые маршрутизируются к действиям контроллера с использованием значения Id. Я создал следующий маршрут с помощью кетчуп всех параметровMVC Dynamic Routes

routes.MapRoute(
      "RouteName",             
      "{id}/{*Url}", 
      new { controller = "Controller", action = "Action", id = "" } 
     ); 

Это работает, как ожидалось, и позволяет мне использовать следующие Urls:

«http://website.com/1/fake/url/path» (1 будучи идентификатор, который переходит в руки метод действия)

кто-нибудь знает способ добиться его таким образом вместо того, чтобы не создавать свой собственный модуль HTTP ?:

«http://website.com/fake/url/path/1»

Thanks - Mark

+0

Итак, вы хотите произвольное количество сегментов перед параметром id? – Haacked 2008-11-18 16:59:09

ответ

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)); 
    } 
} 
+0

Спасибо Hellfire. у меня не было возможности попробовать, но похоже, что я ищу. – 2008-11-28 20:16:33

+0

Теперь ModelBinderResult недоступен в System.Web.Mvc 2.0.0.0 – 2009-08-31 10:31:07

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

Перенаправление маршрутов основано на вводе маршрута в таблице маршрутов. Это должно быть систематически. Например, если у вас есть маршрут «customurl/id» после {controller}/{action}/{id} (по умолчанию mvc), когда вы введете «customurl» в поле url, он примет его как маршрут по умолчанию, а не страницу обнаруженное исключение. Поэтому, если вы хотите использовать собственный маршрут, сначала удалите маршрут по умолчанию. Я так делаю.

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