【问题标题】:c# - @foreach (var item in Model) [duplicate]c# - @foreach(模型中的变量项)[重复]
【发布时间】:2018-09-01 15:03:52
【问题描述】:

这与 NullReferanceException 问题不同,因为我们正在处理一个已被关注点分开的项目,这使得它在某些方面有所不同 - 因为之前的答案是处理一个项目,我们正在处理3 个不同的项目和命名空间。

我不断收到这个:

Line 41:         <th></th>
Line 42:     </tr>
Line 43:     @foreach (var item in Model)
Line 44:     {
Line 45:         <tr>

说明:在执行当前网络请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详情:System.NullReferenceException:对象引用未设置为对象的实例。

这是我的代码:

DVD.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Web;
using System.Data.Entity;

namespace DVDStore.Data.Models
{

    public class DVD
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Title { get; set; }
        public DateTime ReleaseDate { get; set; }
        public decimal Price { get; set; }
        //public byte[] Picture { get; set; }
        // Foreign Key
        public virtual Ratings RatingsID { get; set; }
        // Foreign Key
        public virtual Genres GenresID { get; set; }
        // Foreign Key
        public virtual SalesInfo SalesInfoID { get; set; }
        //Foreign Key
        public virtual ICollection<Actor> Actors { get; set; }
    }


    public class MovieDBContext : DbContext
    {
        public DbSet<DVD> DVDs { get; set; }
    }
}

控制器

using System;
using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using DVDStore.Access.Methods;

namespace DVDStore.WEB.Controllers
{
    public class HomeController : Controller
    {

        public ActionResult Index()
        {

        FindAllDVDs findDVDs = new FindAllDVDs();

            return View(findDVDs);
        }
    }

访问

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DVDStore.Data.Models;
using System.Data;
using System.Data.Entity;
using System.Net;
using System.Web.Mvc;

namespace DVDStore.Access.Methods
{
    public class FindAllDVDs
    {
        //List<FindAllDVDs> dVDs = new List<FindAllDVDs>();

        private DVDStoreContext db = new DVDStoreContext();

        public dynamic ViewBag { get; }

        public void FindAllDVD(string DVDTitles, string searchString)
        {
            var FindDVDS = new List<string>();

            var DVDQuery = from d in db.DVD
                           orderby d.Title
                           select d.Title;

            FindDVDS.AddRange(DVDQuery.Distinct());
            ViewBag.DVDTitles = new SelectList(FindDVDS);

            var dvds = from dvd in db.DVD
                       select dvd;

            if (!String.IsNullOrEmpty(searchString))
            {
                dvds = dvds.Where(s => s.Title.Contains(searchString));
            }
            if (!String.IsNullOrEmpty(DVDTitles))
            {
                dvds = dvds.Where(x => x.Title == DVDTitles);

            }

        }

    }

    }

最后是我遇到问题的 index.schtml

所有东西都编译了,但 0 错误顺便说一句

@*@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}*@

@model IEnumerable<DVDStore.Data.Models.DVD>


@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p></p>

@Html.ActionLink("Create New", "Create")


@using (Html.BeginForm("Index", "DVD", FormMethod.Get))
{
    <p>
        Title: @Html.TextBox("SearchString") <br />
        <input type="submit" value="Filter" />
    </p>
}
}
 </p>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Price)
        </th>
        <th></th>
    </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>

        </tr>
    }

</table>

 </table>

【问题讨论】:

  • 当然它是重复的——如果有多个命名空间项目没有区别。 @foreach (var item in Model) 中的 Modelnull。而且您的 public ActionResult Index() 方法中的代码毫无意义。您所做的就是初始化您的类的一个实例。你甚至没有调用你的 FindAllDVD() 方法,它不会以任何方式返回任何东西。
  • Alex,这个异常只有一个原因:您尝试使用的值为 null。因此,每个 NullReferenceException 问题都是重复的。您重复的问题解释了事物可能为空的所有方式以及如何解决它。

标签: c# database model-view-controller model


【解决方案1】:

您的视图需要DVD 类型模型的集合。

@model IEnumerable<DVDStore.Data.Models.DVD>

但是,在您的 Controller 中,您正在传递一个 FindAllDVDs 的实例。

        FindAllDVDs findDVDs = new FindAllDVDs();
        return View(findDVDs);

您应该传递DVD 对象的列表。

更新:

最快的方法是从您的方法中返回 DVD 对象列表。

public IEnumerable<DVDStore.Data.Models.DVD> FindAllDVD(string DVDTitles, string searchString)

并返回 DVD 列表。

然后在你的控制器中,你可以这样做:

FindAllDVDs findDVDs = new FindAllDVDs();
IEnumerable<Dvd> dvds = findDVDs.FindAllDVD(<DVDTitles>, <searchString>);
return View(dvds);

但是,我不推荐这种方法。您不想将数据模型用作视图模型。我宁愿创建一个单独的 DVD 类作为 View 的模型,然后将 Data 模型映射到这个 View Model。

【讨论】:

  • 我将如何通过它?
  • 最快的方法是从您的方法中返回 DVD 对象列表。
    public IEnumerable&lt;DVDStore.Data.Models.DVD&gt; FindAllDVD(string DVDTitles, string searchString)
    并返回列表Dvds。然后在你的控制器中,你可以这样做:
    FindAllDVDs findDVDs = new FindAllDVDs();
    IEnumerable&lt;Dvd&gt; dvds = findDVDs.FindAllDVD(&lt;DVDTitles&gt;, &lt;searchString&gt;);
    return View(dvds);
    但是,我不推荐这种方法。我宁愿创建一个单独的 DVD 类作为 View 的模型,然后将 Data 模型映射到这个 View Model。
  • 对不起,我的评论有点乱,还在为这种评论格式而苦恼。我用我描述的内容更新了我的答案。
【解决方案2】:

您需要更改您的 FindAllDVD 方法,使其具有:

return dvds;

作为最后一行。这可能意味着将签名更改为:

public IEnumerable<DVD> FindAllDVD(string DVDTitles, string searchString)

那么,您需要将findDVDs.FindAllDVD结果 传递给视图,而不是传递findDVDs

FindAllDVDs findDVDs = new FindAllDVDs();
return View(findDVDs.FindAllDVD("", ""));

这样您的Model 将使用DVDs 的集合,而不是像现在这样使用FindAllDVDs 类的单个实例。

【讨论】:

    【解决方案3】:

    FindAllDVDs 内部,您有the List&lt;FindAllDVDs&gt; dVDs = new List&lt;FindAllDVDs&gt;(); 设置在构造函数中。

    您可以像刚才那样调用构造函数(记得取消注释 dvds 属性,如下所示:

    public List<FindAllDVDs> dVDs = new List<FindAllDVDs>();
    

    并在构造函数中设置值,如下所示:

    dVDs = dvds;
    

    也许你需要做一些演员,像这样:

    dVDs = dvds.toList();
    

    ,并传递FindAllDVDs 中的值,如下所示:

    FindAllDVDs findDVDs = new FindAllDVDs("","");
    
    return View(findDVDs.dvds);
    

    【讨论】:

    • 它似乎无法识别 dvd - 您的意思是取消对 dVD 的注释是否正确?
    • 我现在做了更详细的描述,我想取消注释FindAllDVDs顶部的属性并使用它来获取控制器的值。
    猜你喜欢
    • 2014-11-02
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-14
    • 1970-01-01
    • 2022-06-13
    相关资源
    最近更新 更多