我网站上所有页面的URL看起来如何:WebName / {title}

问题描述 投票:1回答:3

我正在使用Web ASP.NET MVC,我希望Web上的所有页面都具有一个如下所示的唯一URL形式:WebName / {Title}。这是我的客户的要求。

例如:store.com/chicken-pizzastore.com/how-to-cook-beefsteak,但不是:store。 com / foods / chicken-pizzastore.com/recipe/how-to-cook-beefsteak

我尝试使用RouteConfig:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        /*   store.com/foods => This works well */
        routes.MapRoute(
            name: "List-Foods",
            url: "foods",
            defaults: new { controller = "Food", action = "ListFoods", id = UrlParameter.Optional }
        );

        /*   store.com/chicken-pizza, store.com/cheese-sandwich,... => This works well */
        routes.MapRoute(
            name: "Detail-Food",
            url: "{title}",
            defaults: new { controller = "Food", action = "FoodDetail", id = UrlParameter.Optional }

        );

        /*   store.com/recipes => This works well */
        routes.MapRoute(
            name: "List-Recipes",
            url: "recipes",
            defaults: new { controller = "Recipe", action = "ListRecipes", id = UrlParameter.Optional }
        );

        /*   store.com/how-to-make-beefsteak, 
             store.com/instructions-for-making-cookies,..
             => Conflict occurred... this route can't be touch because it 
             has the same url form as Details-Food (url:{title}) */

        routes.MapRoute(
            name: "Detail-Recipe",
            url: "{title}",
            defaults: new { controller = "Recipe", action = "RecipeDetail", id = UrlParameter.Optional }
        );

        ...............

    }

我意识到route.MapRoute(s)不能具有相同的URL形式(url:“ {title}”))。对于url:“ foods”(以获取食物列表)和url:“ recipes”(以获取食谱列表),这不是问题,因为我在route.Maproute中指定了单词(食品和食谱)。另外,我可以通过“详细信息-食物”路线轻松按{title}获取任何提要的详细信息。但是,该问题发生在“详细信息-配方”路线上,因为它与“详细信息-食品”路线具有相同的url形式(url:{title}),所以我无法触摸“配方/配方详细信息”来获取数据。

c# asp.net-mvc url url-routing routeconfig
3个回答
0
投票

您将无法使用默认路由处理程序来实现此目的,因此您将不得不推出自己的自定义脚本来捕获FoodDetail和RecipeDetail网址。

FoodRecipeRouteHandler.cs

public class FoodRecipeRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        string title = requestContext.RouteData.Values["title"] as string;

        var food = database.GetFoodByTitle(title);

        if (food != null)
        {
            requestContext.RouteData.Values["controller"] = "Food";
            requestContext.RouteData.Values["action"] = "FoodDetail";
        }
        else
        {
            var recipe = database.GetRecipeByTitle(title);

            if (recipe != null)
            {
                requestContext.RouteData.Values["controller"] = "Recipe";
                requestContext.RouteData.Values["action"] = "RecipeDetail";
            }
        }

        return base.GetHttpHandler(requestContext);
    }
}

RouteConfig

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapRoute(
        name: "FoodRecipeDetail",
        url: "{title}").RouteHandler = new FoodRecipeRouteHandler();
}

[这里发生的是,我们正在捕获格式为{title}的路线,然后在数据库中查找以尝试找到匹配的食物或食谱项目,并将适当的actioncontroller值分配给[C0 ]。这只是一个基本的实现示例,可让您处于正确的轨道。


0
投票

代替此,您可以使用[Route]属性。

RequestContext

阅读更多:[HttpGet] [Route("chicken-pizza")] public ActionResult chickenPizza(){ // Code Here }


0
投票

似乎您正在尝试将相同的方法签名映射到不同的控制器。您需要有另一个独特的网址,以使它们路由到不同的控制器。使用您当前的配置它不知道要路由到哪个控制器(我实际上不确定该行为,但是您很可能会在此处收到错误消息)。

[我想,如果您想遵守自己的命名约定,则可以对食谱页面的URL使用/ how-to-cook- {title}。 (如果您在title参数中有些怪异,则此[[could会令人讨厌)。

© www.soinside.com 2019 - 2024. All rights reserved.