Dictionary需要System.Collections.Generic.List类型的模型项

时间:2015-07-30 20:25:24

标签: c# asp.net-mvc razor

我有一个layout.csthml,它包含一个侧边栏,还包含一个@Renderbody。 @Renderbody和侧边栏都在其各自的视图中使用以下内容。

@model List<appstowindows.Models.apps>
@foreach (var item in  Model){...}

两个视图都可以很好地呈现列表,但是当我尝试在视图中打开编辑URL时,我不断收到错误:

  

传递到字典中的模型项是类型的   System.Data.Entity.DynamicProxies,Dictionary需要一个模型项   键入System.Collections.Generic.List

修改网址

@Html.ActionLink("Edit", "Edit", new { id = item.app_key }) 

索引

    public ActionResult Index()
    {
        var applist = db.apps.Include(a => a.appgroups);
        applist = db.apps.Include(a => a.appstatus);

        return View(applist.ToList());
    }

修改

    public ActionResult Edit(int? id)
    {
        apps apps = db.apps.Find(id);
        return View(apps);
    }

重要说明:如果我要删除其中一个视图中的任何一个列表,编辑网址就可以正常工作。

导致此错误的原因是什么以及如何解决?

更新:

@model myproject.Models.apps
@{
    ViewBag.Title = "Edit";
}
<h2>Edit</h2>

@using (Html.BeginForm("Edit", "Apps", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>apps</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @Html.HiddenFor(model => model.app_key)

</div>
}

1 个答案:

答案 0 :(得分:2)

您正在将错误类型的模型传递给您的视图。传递的对象属于System.Data.Entity.DynamicProxies类型,而System.Collections.Generic.List是必需的。检查提供哪个对象作为参数。

更新: 问题出在布局页面上指定modelEdit视图基于布局页面,因此需要能够呈现List<apps>类型的模型。但Edit视图需要apps作为对方的模型。虽然没有类型,同时List<apps>apps,但您的代码将无效。

通常,您应该避免布局页面输入,因为基于该布局的所有视图都需要相同或后代类型的模型。 如果您的所有页面都应该真正共享一些信息,您可以通过多种选项解决此问题:

  1. 第一个(也是最差的) - 基本视图模型类型,将用作布局的模型。在此解决方案中,所有视图(基于此布局)都应具有基本视图模型后代类型的模型,即所有操作都必须获取基本视图模型以及视图模型本身的数据。
  2. 第二个(我会用它来处理简单的情况) - 在你的布局中调用的子动作。它比以前更好,因为共享视图部分的数据应该只在子操作中检索一次,对于视图模型类型没有限制,并且您的布局可以保持不带模型。它使用组合而不是继承,这更容易支持并且是一种更好的制作方式(您将能够使用此方法轻松添加多个共享信息块,尝试使用第一个实现它)。但是MVC中的子操作受到限制,它们不能async(有一些黑客可以使它们成为async,但事实并非如此)
  3. 第三个(如果应该显示多个共享信息块,我将继续使用它) - 使用js来延迟加载内容块。具有与之前相同的优点,但默认情况下操作可以是async。这些块也不会延迟页面加载,并且可以用旋转器或其他东西进行装饰。
  4. 在您的情况下,错误是由@model List<appstowindows.Models.apps>引起的。在执行Edit视图时,它首先呈现布局页面标记,因此作为apps视图的模型提供的类型Edit的对象不适合。我想,你在你的布局中指定了一个类型,因为在你的所有页面之间共享了一些标记(如果我错了,只需从你的布局中删除@model,一切都会好的)这个共享可能是通过我之前提出的一种方法实现。

    如果你选择第二个,你应该向你的控制器添加一个动作(不知道你正在渲染什么信息,所以我会称之为Foo

    public ActionResult Foo()
    {
        /*get data for your shared content part*/
    
        return PartialView(/*provide data here*/);
    }
    

    然后使用标记创建View,标记应该共享。 (布局中的那个,导致问题)

    @model List<appstowindows.Models.apps>
    @foreach (var item in  Model){...}
    

    然后从您的布局中删除该标记,然后调用@Html.Action("Foo")

    顺便说一下,我想你应该在ASP.MVC中学习一些关于布局页面和模型的信息,官方website是一个很好的起点。