2

我是使用 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

4 回答 4

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
}
于 2013-10-22T14:13:39.190 回答
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 }
    );
}

更新

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

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

@{ 
    Html.RenderAction("Menu", "Nav", new {category = null}); 
} 
于 2013-10-21T14:25:41.933 回答
0

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

于 2013-10-22T15:23:56.077 回答
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>

更新 2

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

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

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

  • .../导航/菜单
  • .../产品列表
  • .../这将等于.../product/list因为默认控制器设置为ProductController并且默认操作设置为List方法。

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

于 2013-10-22T14:24:11.813 回答