【问题标题】:Null Exception thrown in View视图中抛出空异常
【发布时间】:2017-05-22 15:11:24
【问题描述】:

使用 ASP.NET MVC、.NET Framework 4.5.2、SQL DB 实体数据模型、Visual Studio 2017。

我有一个从 ADO.NET(数据库中的 EF 设计器)生成的类:

BookInfo.cs

 namespace LibraryMS
{
 using System;
 using System.Collections.Generic;

public partial class BookInfo
{
    public string BookID { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public string Publisher { get; set; }
    public string PublishDate { get; set; }
    public string Edition { get; set; }

    public virtual Inventory Inventory { get; set; }
}
}

设计数据库时,BookInfo 表中的“BookID”在 Inventory 表中具有外键“BookID”。 为了更新“BookID”引用的库存属性,然后我继续查询列表并更新正确的实例。

更新库存页面的屏幕截图:

当登陆页面输入信息时调用[HttpGet] UpdateInventory(),当点击如上所示的“创建”按钮时,调用[HttpPost] UpdateInventory(...)。

控制器中的逻辑/代码:

    [HttpGet]
    public  ActionResult UpdateInventory()
    {
        return View();
    }


    [HttpPost]
    public async Task<ActionResult> UpdateInventory(string bookID, string ttlIn, string lowin, string outnow)
    {
        var bf = await SqlRestApiHelper.searchFromBooks(bookID);

        bf.Inventory.TotalIn = Convert.ToInt16(ttlIn);
        bf.Inventory.LowIn = Convert.ToInt16(lowin);
        bf.Inventory.Out = Convert.ToInt16(outnow);
        await SqlRestApiHelper.UpdateBookInfoInventory(bf.Inventory);

        await SqlRestApiHelper.SaveChanges();
        return View("All");            
    }

 [HttpGet]
    public async Task<ActionResult> All()
    {
        return View(await SqlRestApiHelper.getAllBooksInfo(0, 10));
    }

SqlRestApiHelper.cs

namespace LibraryMS
{
public static class SqlRestApiHelper
{
   private static libraryDBEntities entities = new libraryDBEntities();


    public static async Task<LibraryMS.BookInfo> searchFromBooks(string id)
    {
       return entities.BookInfoes.ToList().Find(book => book.BookID == id);
    }

    public static async Task UpdateBookInfoInventory(LibraryMS.Inventory inv)
    {
        var newInv = inv;

        var el = entities.BookInfoes.ToList().Find(x => x.Inventory.BookID == newInv.BookID);
        if (el != null) 
        {
            el.Inventory.TotalIn = newInv.TotalIn;
            el.Inventory.LowIn = newInv.LowIn;
            el.Inventory.Out = newInv.Out;
            // the above updates the list item referenced
        }

    }

    public static async Task SaveChanges()
    {
       await entities.SaveChangesAsync();
    }

 public static async Task<IPagedList<BookInfo>> getAllBooksInfo(int page, int itemsPerPage)
    {
        List<BookInfo> bookinfo = new List<BookInfo>();

            bookinfo = (from o in entities.BookInfoes
                      orderby o.Title descending //use orderby, otherwise Skip will throw an error
                      select o)
                      .Skip(itemsPerPage * page).Take(itemsPerPage)
                      .ToList();
        int totalCount = bookinfo.Count();//return the number of pages
        IPagedList<BookInfo> pagebooks = new StaticPagedList<BookInfo>(bookinfo, page + 1,10,totalCount);
        return pagebooks;//the query is now already executed, it is a subset of all the orders.
    }

抛出空异常:

all.cshtml 查看页面的代码:

 @model PagedList.IPagedList<LibraryMS.BookInfo>
 @using PagedList.Mvc;
 @{
ViewBag.Title = "All";
 }

 <h2>all</h2>

 <table class="table">

 @foreach (var item in Model) {
 <tr>
    <td>
        @Html.DisplayFor(modelItem => item.Title)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Author)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Publisher)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.PublishDate)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Edition)
    </td>

    <td>
        @Html.ActionLink("Details","Details",new { item.BookID})
    </td>
</tr>
 }

 </table>

 @Html.PagedListPager(Model, page => Url.Action("All","BookInfoController", new { page }))

【问题讨论】:

  • 您好,您将 BookInfo 模型绑定到 View 了吗?喜欢查看页面顶部的@model BookInfo
  • 嘿,如果你的意思是:@model PagedList.IPagedList 那么是的。
  • 我希望您在列表页面中遇到此错误。如果是这样,您能否告诉我该列表的控制器方法。那么调试会很有帮助。谢谢
  • @KarthikElumalai,请参阅该方法的编辑。谢谢
  • 显示您的视图代码,所有这些,您使用的是模型还是什么? null 异常是因为您使用的是模型,但我猜您没有将其传递给您的视图,请添加完整代码以便我们提供帮助

标签: c# asp.net-mvc entity-framework


【解决方案1】:

您的视图抛出错误,因为您在未传递模型的情况下返回视图,您正在使用 return View("All") 而未传递模型 正确的方法是将模型与视图一起传递,您可以这样做 View("ViewName", ModelData);

在你的情况下

return View("All", await SqlRestApiHelper.getAllBooksInfo(0, 10));

对于保存部分我不知道为什么,但我可以看到一些错误, 首先,如果书没有库存信息怎么办? 它会抛出空错误,所以首先检查是否为空,创建新库存,如果没有相应更新 这是我会怎么做的

 public static async Task UpdateBookInfoInventory(Inventory inv)
 {
    var newInv = inv;
     // get book info
    var el = entities.BookInfoes.FirstOrDefault(x => x.BookID == inv.BookID);
    if (el != null) 
    {
         if(el.Inventory != null)
       {
           // update accordingly
        el.Inventory.TotalIn = newInv.TotalIn;
        el.Inventory.LowIn = newInv.LowIn;
        el.Inventory.Out = newInv.Out;
        // the above updates the list item referenced
    }
    else
      { 
        /// add new if null 
         el.inventory = newInv;  
     }
   await SqlRestApiHelper.SaveChanges();

}

【讨论】:

  • 谢谢! return View("All", await SqlRestApiHelper.getAllBooksInfo(0, 10));修复了空引用问题。
  • 如果答案有帮助,请投票,如果它完全解决问题标记正确,让我知道更新是否有效,所以我可以提供帮助。很高兴我能帮上忙。
  • 我会将此标记为答案,因为我的方法是数据肯定在数据库中,一旦创建新书,链接的库存信息也会创建,但值设置为“0” .所以它确实存在。是的,更新也有效。
  • 谢谢,我很高兴能帮上忙。快乐编码
【解决方案2】:

作为第一步,将断点放在 getAllBooksInfo 方法中,并在 Visual Studio 中查看列表计数是否即将到来。这对你有很大帮助。

作为替代步骤,您还可以通过使用 ToPagedList(pageIndex, pageSize); 来解决此错误。方法,我个人用过,效果很好

根据您的代码的 ToPagedList 示例:

     **public static async Task<IPagedList<BookInfo>> getAllBooksInfo(int page, int itemsPerPage)
        {
            List<BookInfo> bookinfo = new List<BookInfo>();

                bookinfo = (from o in entities.BookInfoes
                          orderby o.Title descending //use orderby, otherwise Skip will throw an error
                          select o)
                          .Skip(itemsPerPage * page).Take(itemsPerPage)
                          .ToList();
            int totalCount = bookinfo.Count();//return the number of pages

//changes made to the below line

            IPagedList<BookInfo> pagebooks = bookinfo.ToPagedList(1, 10);


            return pagebooks;//the query is now already executed, it is a subset of all the orders.
        }**

官方来源:https://github.com/troygoode/PagedList

注意:即使使用这种方法,请使用更改行中的断点检查您是否从数据库中获取数据。

希望这一定能解决您的问题,请让我知道想法或反馈

谢谢

卡提克

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-02
    • 2012-09-09
    • 2015-09-25
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-17
    相关资源
    最近更新 更多