当我的 table 不可枚举时,如何显示来自 SQL 数据库的列表?我可以很好地使用详细信息视图,但不能使用索引视图
How do I display a list from SQL database when my table is not enumerable? I can use details view fine, but not an index view
我很难让我的索引视图显示我从 SQL 数据库中获得的值。
主要问题是我不能使用 @foreach (var item in Model) {...
因为我的 table 不是作为 Enumerable 创建的(我认为)。我运行进入错误信息System.NullReferenceException: 'Object reference not set to an instance of an object.'
,指向foreach
语句表达式中的Model
。
我想知道是否需要将 table 设置为可枚举列表,然后显示每个项目。或者,如果我遗漏了与我的索引视图有关的某些内容。或者我可能需要通过索引传递一些东西 return View()
?
这是图像模型:
namespace Uploadimage.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web;
public partial class Image
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string Phone { get; set; }
[Required]
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",
ErrorMessage = "Email doesn't look like a valid email address.")]
public string Email { get; set; }
[Compare("Email", ErrorMessage = "Emails do not match.")]
public string ConfirmEmail { get; set; }
[DisplayName("Upload File")]
public string ImagePath { get; set; }
public HttpPostedFileBase ImageFile { get; set; }
}
}
这是控制器:
public class ImageController : Controller
{
[HttpGet]
public ActionResult Add()
{
return View();
}
[HttpPost]
public ActionResult Add(Image imageModel)
{
string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
string extension = Path.GetExtension(imageModel.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
imageModel.ImagePath = "~/Image/" + fileName;
fileName = Path.Combine(Server.MapPath("~/Image/"), fileName);
imageModel.ImageFile.SaveAs(fileName);
using(LoginDBEntities db = new LoginDBEntities())
{
db.Images.Add(imageModel);
db.SaveChanges();
}
ModelState.Clear();
return View();
}
[HttpGet]
public ActionResult View(int id)
{
Image imageModel = new Image();
using (LoginDBEntities db = new LoginDBEntities())
{
imageModel = db.Images.Where(x => x.Id == id).FirstOrDefault();
}
return View(imageModel);
}
public ActionResult Index()
{
return View();
}
}
最后,我的索引视图:
@model IEnumerable<Uploadimage.Models.Image>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.LastName)
</th>
<th>
@Html.DisplayNameFor(model => model.City)
</th>
<th>
@Html.DisplayNameFor(model => model.Province)
</th>
<th>
@Html.DisplayNameFor(model => model.Phone)
</th>
<th>
@Html.DisplayNameFor(model => model.Email)
</th>
<th>
@Html.DisplayNameFor(model => model.ImagePath)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.Province)
</td>
<td>
@Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.ImagePath)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
我已尝试彻底查找,但发现了一些不适用于我的内容。
或者我不知道该查什么。
您的 Index 方法中没有任何可获取实体列表的内容。
控制器中的 Index 方法应该类似于:
public ActionResult Index()
{
var model = db.Images.ToList();
return View(model);
}
两件事:
您的索引控制器操作需要加载图像以传递给视图。至少要提供一组图像作为视图的“模型”:
public ActionResult Index()
{
using (LoginDBEntities db = new LoginDBEntities())
{
var images = db.Images.ToList();
return View(images);
}
}
然后在视图中你需要检查你是否真的得到任何结果,然后如果有的话从第一个结果中提取你的标签,或者如果没有图像则显示合适的消息:
<!-- ... -->
@if (Model.Any())
{
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.ElementAt(0).FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.ElementAt(0).LastName)
</th>
...
</tr>
@for (int count = 0; count < Model.Count; count++) {
<tr>
<td>
@Html.DisplayFor(model => model.ElementAt(count).FirstName)
</td>
<td>
@Html.DisplayFor(model => model.ElementAt(count).LastName)
</td>
...
<td>
@Html.ActionLink("Edit", "Edit", new { id=@Model.ElementAt(count).Id }) |
@Html.ActionLink("Details", "Details", new { id=@Model.ElementAt(count).Id }) |
@Html.ActionLink("Delete", "Delete", new { id=@Model.ElementAt(count).Id })
</td>
</tr>
}
</table>
}
else
{
<p> No Images. </p>
}
以上是凭记忆写的,因此可能存在一些语法问题,但它应该为您指明了正确的方向。
通常在处理搜索结果等集合时,我会为本身包含结果集合的结果页面定义一个视图模型 class。页面的模型变成了包装器视图模型,它可以包含页面的详细信息(例如当前搜索条件、搜索的查找值等)以及结果集合。 (通常是支持分页的 PagedList)
即
[Serializable]
public class ImageIndexViewModel
{
public string NameSearchString { get; set; }
public ICollection<ImageViewModel> Results { get; set; } = new List<ImageViewModel>();
}
其中 ImageViewModel 是一个可序列化的 POCO 视图模型,仅表示有关视图将显示的图像的详细信息。通常视图不需要关于数据行的一切,并且在数据行具有导航属性和我们不需要显示的额外字段的情况下,序列化实体会导致延迟加载调用或只是发送大量不需要的额外数据。
我很难让我的索引视图显示我从 SQL 数据库中获得的值。
主要问题是我不能使用 @foreach (var item in Model) {...
因为我的 table 不是作为 Enumerable 创建的(我认为)。我运行进入错误信息System.NullReferenceException: 'Object reference not set to an instance of an object.'
,指向foreach
语句表达式中的Model
。
我想知道是否需要将 table 设置为可枚举列表,然后显示每个项目。或者,如果我遗漏了与我的索引视图有关的某些内容。或者我可能需要通过索引传递一些东西 return View()
?
这是图像模型:
namespace Uploadimage.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web;
public partial class Image
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string Phone { get; set; }
[Required]
[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}",
ErrorMessage = "Email doesn't look like a valid email address.")]
public string Email { get; set; }
[Compare("Email", ErrorMessage = "Emails do not match.")]
public string ConfirmEmail { get; set; }
[DisplayName("Upload File")]
public string ImagePath { get; set; }
public HttpPostedFileBase ImageFile { get; set; }
}
}
这是控制器:
public class ImageController : Controller
{
[HttpGet]
public ActionResult Add()
{
return View();
}
[HttpPost]
public ActionResult Add(Image imageModel)
{
string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
string extension = Path.GetExtension(imageModel.ImageFile.FileName);
fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
imageModel.ImagePath = "~/Image/" + fileName;
fileName = Path.Combine(Server.MapPath("~/Image/"), fileName);
imageModel.ImageFile.SaveAs(fileName);
using(LoginDBEntities db = new LoginDBEntities())
{
db.Images.Add(imageModel);
db.SaveChanges();
}
ModelState.Clear();
return View();
}
[HttpGet]
public ActionResult View(int id)
{
Image imageModel = new Image();
using (LoginDBEntities db = new LoginDBEntities())
{
imageModel = db.Images.Where(x => x.Id == id).FirstOrDefault();
}
return View(imageModel);
}
public ActionResult Index()
{
return View();
}
}
最后,我的索引视图:
@model IEnumerable<Uploadimage.Models.Image>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.LastName)
</th>
<th>
@Html.DisplayNameFor(model => model.City)
</th>
<th>
@Html.DisplayNameFor(model => model.Province)
</th>
<th>
@Html.DisplayNameFor(model => model.Phone)
</th>
<th>
@Html.DisplayNameFor(model => model.Email)
</th>
<th>
@Html.DisplayNameFor(model => model.ImagePath)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.Province)
</td>
<td>
@Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.ImagePath)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
我已尝试彻底查找,但发现了一些不适用于我的内容。
或者我不知道该查什么。
您的 Index 方法中没有任何可获取实体列表的内容。 控制器中的 Index 方法应该类似于:
public ActionResult Index()
{
var model = db.Images.ToList();
return View(model);
}
两件事:
您的索引控制器操作需要加载图像以传递给视图。至少要提供一组图像作为视图的“模型”:
public ActionResult Index()
{
using (LoginDBEntities db = new LoginDBEntities())
{
var images = db.Images.ToList();
return View(images);
}
}
然后在视图中你需要检查你是否真的得到任何结果,然后如果有的话从第一个结果中提取你的标签,或者如果没有图像则显示合适的消息:
<!-- ... -->
@if (Model.Any())
{
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.ElementAt(0).FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.ElementAt(0).LastName)
</th>
...
</tr>
@for (int count = 0; count < Model.Count; count++) {
<tr>
<td>
@Html.DisplayFor(model => model.ElementAt(count).FirstName)
</td>
<td>
@Html.DisplayFor(model => model.ElementAt(count).LastName)
</td>
...
<td>
@Html.ActionLink("Edit", "Edit", new { id=@Model.ElementAt(count).Id }) |
@Html.ActionLink("Details", "Details", new { id=@Model.ElementAt(count).Id }) |
@Html.ActionLink("Delete", "Delete", new { id=@Model.ElementAt(count).Id })
</td>
</tr>
}
</table>
}
else
{
<p> No Images. </p>
}
以上是凭记忆写的,因此可能存在一些语法问题,但它应该为您指明了正确的方向。
通常在处理搜索结果等集合时,我会为本身包含结果集合的结果页面定义一个视图模型 class。页面的模型变成了包装器视图模型,它可以包含页面的详细信息(例如当前搜索条件、搜索的查找值等)以及结果集合。 (通常是支持分页的 PagedList)
即
[Serializable]
public class ImageIndexViewModel
{
public string NameSearchString { get; set; }
public ICollection<ImageViewModel> Results { get; set; } = new List<ImageViewModel>();
}
其中 ImageViewModel 是一个可序列化的 POCO 视图模型,仅表示有关视图将显示的图像的详细信息。通常视图不需要关于数据行的一切,并且在数据行具有导航属性和我们不需要显示的额外字段的情况下,序列化实体会导致延迟加载调用或只是发送大量不需要的额外数据。