Razor Partial View Error
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.RouteValueDictiona开发者_如何学运维ry(
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)%>
<% } %>
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"} );
Try updating the Menu function in your controller to return PartialView
public PartialViewResult Menu()
{
.
.
return PartialView(NavLinks)
}
精彩评论