我网站所有页面的 URL 是怎样的:WebName/{title}

How do the URLs of all pages of my site look like: WebName/{title}

我正在开发网络 ASP.NET MVC,我希望我网络上的所有页面都有一个独特的 URL 形式,如下所示:WebName/{Title}。这是我客户的要求。

例如:store.com/chicken-pizzastore.com/how-to-cook-beefsteak,但不是:store.com/foods/chicken-pizza and 商店.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 }
        );

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

    }

我意识到 routes.MapRoute(s) 不能有相同的 URL 形式 (url:"{title}")。 对于 url:"foods"(获取食物列表)和 url:"recipes"(获取食谱列表)因为我在[=62中指定了单词(食物和食谱) =].此外,我可以通过 Detail-Food 路线轻松获取 {title} 的任何提要的详细信息。但是,问题出现在 Detail-Recipe 路线,因为它与 Detail-Food 路线具有相同的 url 形式(url:{title}),我无法触摸 Recipe/RecipeDetail 到获取数据。

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

我想如果您想保持现有的命名约定,可以将 /how-to-cook-{title} 用于食谱页面的 url。 (这 可能会 变得冒险,如果你在标题参数中有一些奇怪的话)。

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

[HttpGet]
[Route("chicken-pizza")]
public ActionResult chickenPizza(){
 // Code Here
}

阅读更多:Web API Route and Route Prefix: Part 2 by Jasminder Singh.

您将无法使用默认路由处理程序完成此操作,您将不得不推出您自​​己的自定义路由处理程序来捕获 FoodDetail 和 RecipeDetail url。

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

路由配置

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

这里发生的事情是我们正在捕获格式为 {title} 的路线,然后在数据库中查找以尝试找到匹配的食物或食谱项目并分配适当的 actioncontroller 值到 RequestContext。这只是一个基本的实施示例,可以让您走上正轨。