如何在URL路由中映射模型数据?

时间:2017-01-21 23:25:59

标签: c# asp.net-mvc

我有一个索引页面,其中显示了带有URL请求的类别(具有属性:id和name):http://localhost:62745/home/index

当我点击某个类别时,我将被带到http://localhost:62745/Home/Products/6

我想让网址更加详细,并将之前网址中的类别ID属性6替换为刚刚点击的类别的name属性。

我的路线配置如下:

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

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

            routes.MapRoute(
                name: "Categories",
                url: "{controller}/{action}/{categoryName}",
                defaults: new { controller = "Category", action = "Index", categoryName = UrlParameter.Optional }
            );

        }
    }

第一个MapRoute()方法已经实施。我添加了第二个希望解决我的问题,但它没有。

这是我对产品的控制器操作:

// GET: Product
public async Task<ActionResult> Index(int? id, string categoryName)
{

    var products = (await db.Categories.Where(c => c.Id == id)
                                    .SelectMany(p => p.Products.Select(x => new ProductViewModel { Id = x.Id, Name = x.Name, ByteImage = x.Image, Price = x.Price}))
                                    .ToListAsync());

    categoryName = db.Categories.Where(c => c.Id == id).Select(c => c.Name).ToString();

    if (products == null)
    {
        return HttpNotFound();
    }

    return View(new ProductIndexViewModel{ Products = products, CategoryId = id });
}

1 个答案:

答案 0 :(得分:1)

您的路线在解释方式上都是相同的 - 它们接受2段和可选的第3段,因此Home/Products/6Home/Products/CategoryName都匹配第一条Default路线(有没有什么可以区分第二条Categories路线,所以永远不会被击中。

您的问题是指第二个网址中的Products()方法,但您没有显示该方法,因此,如果您引用的是产品名称或类别名称,但主体是相同的,则不清楚。

假设您希望网址Home/Products/ProductName显示特定产品,请在视图中

@foreach(var item in Model.Products)
{
    // link for each product
    @Html.ActionLink("Details", "Products", "Home", new { id = item.Name }, null)

然后你可以简单地制作方法

public ActionResult Products(string id)
{
    // the value of id is the the the product name
    ....
}

或者,如果您希望参数为string name而不是string id,则可以定义特定路线并将其放在Default路线之前。

routes.MapRoute(
    name: "ProductDetails",
    url: "Home/Products/{name}",
    defaults: new { controller = "Home", action = "Products", name = UrlParameter.Optional }
);

使方法成为

public ActionResult Products(string name)

附注:您在Index()方法中查询获取类别名称的事实表明您可能还需要“slug”路线,在这种情况下,请参阅how to implement url rewriting similar to SO