MVC4错误 - 路由表中没有路由匹配

时间:2013-10-18 19:54:04

标签: c# asp.net-mvc asp.net-mvc-4 asp.net-mvc-routing

我是C#和MVC4编程的新手,错误发生在

@{ 
  Html.RenderAction("Menu", "Nav"); 
} 

它返回时返回错误,指出路由表中没有路由与提供的值匹配。我试过在互联网上搜索无济于事,任何帮助将不胜感激。感谢

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <link href="~/Content/Site.css" type="text/css" rel="stylesheet" />
</head>
<body>
   <div id="header">
       <div class="title">Bag Labels</div>
   </div>
    <div id="categories">
        @{ Html.RenderAction("Menu", "Nav"); }
    </div>
    <div id="content">
         @RenderBody()
    </div>
</body>
</html>

这是_Layout.cshtml

这是我的NavController.cs

using NavisionStore.Domain.Abstract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace NavisionStore.WebUI.Controllers
{
    public class NavController : Controller
    {
        private IProductRepository repository;

        public NavController(IProductRepository repo)
        {
            repository = repo;
        }
        public PartialViewResult Menu(string category = null)
        {
            ViewBag.SelectedCategory = category;

            IEnumerable<string> categories = repository.Products
                .Select(x => x.Category)
                .Distinct()
                .OrderBy(x => x);

            return PartialView(categories);  
        }
    }
}

这是我的RouteConfig.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

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

            routes.MapRoute(null,
                "",
                new { 
                    controller = "Product", action = "List",
                    category = (string)null, page = 1
                }
            );

            routes.MapRoute(null,
                "Page{page}",
                new { controller = "Product", action = "List", category = (string)null },
                new { page = @"\d+" }
            );

            routes.MapRoute(null,
                "{category}",
                new { controller = "Product", action = "List", page = 1 }
        );

            routes.MapRoute(null,
                "{category}/Page{page}",
                new { controller = "Product", action = "List" },
                new { page = @"\d+" }
        );

            routes.MapRoute(null, "{contoller}/{action}");
        }
    }
}

这是我的ProductController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NavisionStore.Domain.Abstract;
using NavisionStore.Domain.Entities;
using NavisionStore.WebUI.Models;



namespace NavisionStore.WebUI.Controllers
{
    public class ProductController : Controller
    {
        private IProductRepository repository;
        public int PageSize = 1;

        public ProductController(IProductRepository productRepository)
        {
            this.repository = productRepository;
        }

        public ViewResult List(string category, int page = 1)
        {
            ProductsListViewModel ViewModel = new ProductsListViewModel
            {
                Products = repository.Products
                .Where(p => category == null || p.Category == category)
                .OrderBy(p => p.Id)
                .Skip((page - 1) * PageSize)
                .Take(PageSize),
                 PagingInfo = new PagingInfo
                {
                    CurrentPage = page,
                    ItemsPerPage = PageSize,
                    TotalItems = repository.Products.Count()
                },
                CurrentCategory = category
            };

            return View(ViewModel);
        }
    }
}

4 个答案:

答案 0 :(得分:0)

您正在使用

  

Html.RenderAction

所以请尝试

public ActionResult Menu(string category = null)
{
    // Your controller code.

    return View(categories);  
}

而不是

public PartialViewResult Menu(string category = null)
{
    // Your controller code.

    return PartialView(categories);  
}

看起来你也错过了你的默认路线映射

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "[Your default controller name goes here]", 
    action = "[Your default action name goes here]", id = UrlParameter.Optional}
);

<强>更新

我不知道是否需要在RouteConfig.cs文件中指定的所有路由规则。保持尽可能简单,例如

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

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

<强>更新

您的菜单操作需要一个类别参数,因此您必须将其传递一个,或设置正确的路线映射。所以改变

@{ 
    Html.RenderAction("Menu", "Nav"); 
} 

@{ 
    Html.RenderAction("Menu", "Nav", new {category = null}); 
} 

答案 1 :(得分:0)

从路由配置中删除以下路由:

routes.MapRoute(null,
     "",
     new { 
        controller = "Product", action = "List",
        category = (string)null, page = 1
    }
);


routes.MapRoute(null, "{contoller}/{action}");

此外,以下路由可能无法满足您的期望,因为每个路由实际上为每个匹配的URL返回相同的控制器/操作。我建议删除它们。

routes.MapRoute(null,
            "Page{page}",
            new { controller = "Product", action = "List", category = (string)null },
            new { page = @"\d+" }
        );

        routes.MapRoute(null,
            "{category}",
            new { controller = "Product", action = "List", page = 1 }
    );

        routes.MapRoute(null,
            "{category}/Page{page}",
            new { controller = "Product", action = "List" },
            new { page = @"\d+" }
    );

可以用以下内容替换它们:

routes.MapRoute(
   "Page",
   "Product/List/{category}/{page}",
   new { controller = "Product", action = "List", page = UrlParameter.Optional },
   new { page = @"\d*" }
);

最后,为所有路线添加名称,而不是null。目前,您唯一命名的是“默认”。

最后,您应该采用更简单的路由配置来实现您的目标:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

// matches:
// product/list/unicorns
// product/list/carrots/15
routes.MapRoute(
   "Page",
   "Product/List/{category}/{page}",
   new { controller = "Product", action = "List", page = UrlParameter.Optional },
   new { page = @"\d*" } //<-- note the asterisk here
);

routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new {controller = "Product", action = "List",
            id = UrlParameter.Optional
}

答案 2 :(得分:0)

如果您在每个页面上只需要一段HTML,就可以使用部分视图

@Html.Patial("_Menu")

而不是

@{ Html.RenderAction("Menu", "Nav"); }

此处 _Menu 是部分视图的名称 _Menu.cshtml (应放置在Views / Shared中)

更新1

如果你需要将一些对象(比如 collection )传递给局部视图,只需将其指定为第二个参数:

@Html.Patial("_Menu", collection)

集合对象将是 _Menu.cshtml 视图中的模型,因此您可以照常使用它:

@model System.Collections.Generic.IEnumerable<string>

<select>
@foreach(var item in Model)
{
    <option>@item</option>
}
</select>

UPDAET 2

你的路线规则太奇怪了。为什么不使用默认路由:

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

这将允许您像这样调用您的操作:

  • ... / NAV /菜单
  • ... /产品/列表
  • ... / 等于 ... / product / list ,因为默认控制器设置为 ProductController ,默认操作为设置为列表方法。

在路线规则中,您始终必须指定唯一名称和模板。但是你将空字符串作为规则名称传递 - 这是错误的。您应该将 RouteConfig.cs 整个替换为他的答案中提到的@ user65439。

答案 3 :(得分:0)

查理布朗解决了我的愚蠢错误。我把最后一条路线上的“控制器”拼错为“控制器”。我觉得和白痴一样,我已经错过了一个月的拼写错误了。谢谢你的帮助,我很感激。