【问题标题】:MVC 5 Multiple ModelsMVC 5 多个模型
【发布时间】:2014-04-30 12:48:15
【问题描述】:

一页内可以有多个@Model 函数吗?

我有一个 Views/Shared/_layout.cshtml 页面,其中包含以下代码以从 SQL Server 2012 数据库中提取导航:

@model IEnumerable<WebApplication1.navigation_V>

<ul class="nav sf-menu clearfix">
    @foreach (var item in Model) {
        <li>@Html.MenuItem(item.title_TV, item.url_TV, "Home")</li>
    }
</ul>

这适用于 Views/Home 文件夹中的所有视图,但是 View/Accounts/Login.cshtml 文件具有以下代码:

@model WebApplication1.Models.LoginViewModel

现在我在尝试查看帐户/登录页面时收到以下错误:

传入字典的模型项的类型为“System.Collections.Generic.List`1[WebApplication1.navigation_V]”,但此字典需要类型为“WebApplication1.Models.LoginViewModel”的模型项。

在编写代码时,我没有看到任何红色下划线曲线,该错误仅在尝试访问帐户/登录页面时触发。这个导航功能必须在所有页面上都可以查看,我接下来担心的实际上是将其余页面内容从数据库中获取到这些页面中。

任何帮助将不胜感激:-)

有关更多信息,我已包含更多代码。

WebApplication1Entities.cs

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

namespace WebApplication1
{    
    public partial class WebApplication1Entities : DbContext
    {
        public WebApplication1Entities()
            : base("name=WebApplication1Entities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public virtual DbSet<navigation_V> navigation_V { get; set; }
    }
}   

navigation_V.cs

using System;
using System.Collections.Generic;

namespace WebApplication1
{
    public partial class navigation_V
    {
        public int navigation_ID { get; set; }
        public string title_TV { get; set; }
        public string url_TV { get; set; }
    }
}

Controllers/HomeController.cs:

public static class MenuExtensions
{
    public static MvcHtmlString MenuItem(
        this HtmlHelper htmlHelper,
        string text,
        string action,
        string controller
    )
    {
        var li = new TagBuilder("li");
        var routeData = htmlHelper.ViewContext.RouteData;
        var currentAction = routeData.GetRequiredString("action");
        var currentController = routeData.GetRequiredString("controller");
        if (string.Equals(currentAction, action, StringComparison.OrdinalIgnoreCase) &&
            string.Equals(currentController, controller, StringComparison.OrdinalIgnoreCase))
        {
            li.AddCssClass("active");
        }
        li.InnerHtml = htmlHelper.ActionLink(text, action, controller).ToHtmlString();
        return MvcHtmlString.Create(li.ToString());
    }
}

namespace WebApplication1.Controllers
{
    public class HomeController : Controller
    {
        private WebApplication1Entities db = new WebApplication1Entities();

        public ActionResult Index()
        {
            return View(db.navigation_V.ToList());
        }
    }
}

Views/Shared/Layout.cshtml

@model IEnumerable<WebApplication1.navigation_V>

<ul class="nav sf-menu clearfix">
    @foreach (var item in Model) {
        <li>@Html.MenuItem(item.title_TV, item.url_TV, "Home")</li>
    }
</ul>

我希望这能让事情更清楚一点。

【问题讨论】:

  • 不可能。但是您可以在布局页面上使用接口而不是类,并让内页模型实现该接口。
  • 我没看懂,每个页面都需要返回多个数据集,能否提供一个简单的例子?
  • 在哪里创建和传递List&lt;navigation_V&gt; 的实例?邮政编码。
  • 请看我修改后的帖子。
  • 好的,但是AccountController.Login 方法中有什么代码?无论如何,我现在会发布一个答案,如果有必要会更新它。

标签: asp.net-mvc sql-server-2012 viewcontroller


【解决方案1】:

您可以在 Home 控制器中编写子操作,而不是在布局中呈现导航 IEnumerable:

[ChildActionOnly]
public ActionResult Navigation()
{
    var navigationModel = ..
    // your code to retrieve IEnumerable<WebApplication1.navigation_V>
    // from DB

    return View(navigationModel);
}

此操作的视图是 Views/Home/Navigation.cshtml:

@{ Layout = null; } // preventing recursive rendering
@model IEnumerable<WebApplication1.navigation_V>

<ul class="nav sf-menu clearfix">
    @foreach (var item in Model) {
        <li>@Html.MenuItem(item.title_TV, item.url_TV, "Home")</li>
    }
</ul>

还有 _layout.cshtml 的代码,用这个替换旧的导航代码:

@{ Html.RenderAction("Navigation", "Home"); }

【讨论】:

  • 我刚刚编辑了我的帖子以包含更多代码,但不知道如何重组。
  • 非常感谢您的代码有效,我注意到的唯一问题是活动类未应用于 MenuItem 函数,我认为这可能是因为代码现在驻留在 View/Navigation.cshtml页面因此未在 _Layout.cshtml 中调用,因此未检测到正确的 URL,您能否建议我如何解决此问题。
  • 修改了 MenuExtensions 类以使用 var currentController = htmlHelper.ViewContext.ParentActionViewContext.RouteData.GetRequiredString("controller"); var currentAction = htmlHelper.ViewContext.ParentActionViewContext.RouteData.GetRequiredString("action");一切都很好,再次感谢您:-)
猜你喜欢
  • 2014-06-25
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多