Динамические маршруты MVC - PullRequest
3 голосов
/ 17 ноября 2008

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

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

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

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

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

"http://website.com/fake/url/path/1"

Спасибо - Марк

Ответы [ 3 ]

1 голос
/ 18 ноября 2014

Перенаправление маршрутов основано на записи маршрута в таблице маршрутов. Это должно быть систематически. Например, если у вас есть маршрут как «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 }
                            );
1 голос
/ 19 ноября 2008

Это действительно очень сложно для меня.

С учетом следующего маршрута:

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 голосов
/ 13 августа 2009

Я бы предложил переопределить 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
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...