Razor 部分视图错误

发布于 2024-11-04 14:13:11 字数 3662 浏览 2 评论 0原文

我正在关注 Pro ASP.NET MVC 2 Framework (但我使用 Razor 而不是 ASPX)。

然而,我的观点有些偏颇,遇到了障碍。我收到以下错误:

The model item passed into the dictionary is of type
'SportsStore.WebUI.Models.ProductsListViewModel', but this dictionary requires a model
item of type 'System.Collections.Generic.IEnumerable`1[SportsStore.WebUI.Models.NavLink]'.

以下是相关文件:

_Layout.cshtml:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" href="@Url.Content("~/Content/global.css")" />
    <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")"><script>
</head>

<body>
    <header>
        <h1>SPORTS STORE</h1>
    </header>
    <nav class="categories">
        @{ Html.RenderAction("Menu", "Nav"); } // <!-- HERE IS THE PROBLEM -->
    </nav>
    <section id="content">
        @RenderBody()
    </section>
</body>
</html>

Menu.cshtml(部分视图):

@model IEnumerable<SportsStore.WebUI.Models.NavLink>

@foreach (var link in Model)
{
    @Html.RouteLink(link.Text, link.RouteValues);
}

NavController.cs:

namespace SportsStore.WebUI.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using SportsStore.Domain.Abstract;
    using SportsStore.WebUI.Models;


    public class NavController : Controller
    {
        private IProductsRepository productsRepository;


        public NavController(IProductsRepository productsRepository)
        {
            this.productsRepository = productsRepository;
        }


        public ViewResult Menu()
        {
            Func<string, NavLink> makeLink = categoryName => new NavLink
            {
                Text = categoryName ?? "Home",
                RouteValues = new System.Web.Routing.RouteValueDictionary(
                    new
                    {
                        controller = "Products",
                        action = "List",
                        category = categoryName,
                        page = 1
                    })
            };

            List<NavLink> navLinks = new List<NavLink>
            {
                makeLink(null)
            };

            var categories = productsRepository.Products.Select(x => x.Category);

            foreach(var categoryName in categories.Distinct().OrderBy(x => x))
                navLinks.Add(makeLink(categoryName));

            return View(navLinks);
        }
    }
}

NavLink.cs (视图模型类):

namespace SportsStore.WebUI.Models
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Routing;


    public class NavLink
    {
        public string Text { get; set; }
        public RouteValueDictionary RouteValues { get; set; }
    }
}

编辑: 当我使用 ASCX 部分视图而不是剃刀部分视图时,以下效果很好:

<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<SportsStore.WebUI.Models.NavLink>>" %>
<% foreach (var link in Model) { %>
    <%: Html.RouteLink(link.Text, link.RouteValues)%>
<% } %>

I'm following the example website being built in Pro ASP.NET MVC 2 Framework (but using Razor instead of ASPX as I go along).

However, I've hit a snag with a partial view. I'm getting the following error:

The model item passed into the dictionary is of type
'SportsStore.WebUI.Models.ProductsListViewModel', but this dictionary requires a model
item of type 'System.Collections.Generic.IEnumerable`1[SportsStore.WebUI.Models.NavLink]'.

Here are the relevant files:

_Layout.cshtml:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" href="@Url.Content("~/Content/global.css")" />
    <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")"><script>
</head>

<body>
    <header>
        <h1>SPORTS STORE</h1>
    </header>
    <nav class="categories">
        @{ Html.RenderAction("Menu", "Nav"); } // <!-- HERE IS THE PROBLEM -->
    </nav>
    <section id="content">
        @RenderBody()
    </section>
</body>
</html>

Menu.cshtml (the partial view):

@model IEnumerable<SportsStore.WebUI.Models.NavLink>

@foreach (var link in Model)
{
    @Html.RouteLink(link.Text, link.RouteValues);
}

NavController.cs:

namespace SportsStore.WebUI.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using SportsStore.Domain.Abstract;
    using SportsStore.WebUI.Models;


    public class NavController : Controller
    {
        private IProductsRepository productsRepository;


        public NavController(IProductsRepository productsRepository)
        {
            this.productsRepository = productsRepository;
        }


        public ViewResult Menu()
        {
            Func<string, NavLink> makeLink = categoryName => new NavLink
            {
                Text = categoryName ?? "Home",
                RouteValues = new System.Web.Routing.RouteValueDictionary(
                    new
                    {
                        controller = "Products",
                        action = "List",
                        category = categoryName,
                        page = 1
                    })
            };

            List<NavLink> navLinks = new List<NavLink>
            {
                makeLink(null)
            };

            var categories = productsRepository.Products.Select(x => x.Category);

            foreach(var categoryName in categories.Distinct().OrderBy(x => x))
                navLinks.Add(makeLink(categoryName));

            return View(navLinks);
        }
    }
}

NavLink.cs (the View-Model class):

namespace SportsStore.WebUI.Models
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Routing;


    public class NavLink
    {
        public string Text { get; set; }
        public RouteValueDictionary RouteValues { get; set; }
    }
}

EDIT:
The following works fine when I use an ASCX Partial View, instead of a razor partial view:

<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<SportsStore.WebUI.Models.NavLink>>" %>
<% foreach (var link in Model) { %>
    <%: Html.RouteLink(link.Text, link.RouteValues)%>
<% } %>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

国际总奸 2024-11-11 14:13:11

您想要使用 RenderAction 而不是 RenderPartial,因为 RenderPartial 会为您当前加载的任何其他视图创建当前模型的副本,并将其发送到您的视图(并且从不执​​行您的控制器方法)。 IE RenderPartial 不会调用您的方法..仅调用您的视图。 RenderAction 将调用您的控制器方法,然后调用部分视图。

在您的视图中使用:

@Html.Action("Menu", "Nav")

您的路线很简单(假设有一个通用导航栏并且没有参数)

            routes.MapRoute(
    "NavMenu", // Route name
    "Nav/Menu", // URL with parameters
    new { controller = "Nav", action = "Menu"}
);

You want to use RenderAction and not RenderPartial as RenderPartial makes a copy of the current model used for whatever other view you are currently loading and sends it over to your view (and never executes your controller method). IE RenderPartial does not call your method .. only your view. RenderAction will call your controller method and then the partial view.

In your view use:

@Html.Action("Menu", "Nav")

Your route is simply (assuming a general nav bar and no parameters)

            routes.MapRoute(
    "NavMenu", // Route name
    "Nav/Menu", // URL with parameters
    new { controller = "Nav", action = "Menu"}
);
临走之时 2024-11-11 14:13:11

尝试更新控制器中的 Menu 函数以返回 PartialView

public PartialViewResult Menu()
{
    .
    .
    return PartialView(NavLinks)
}

Try updating the Menu function in your controller to return PartialView

public PartialViewResult Menu()
{
    .
    .
    return PartialView(NavLinks)
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文