简体   繁体   English

视图中抛出Null异常

[英]Null Exception thrown in View

Using ASP.NET MVC, .NET Framework 4.5.2, Entity Data Model for SQL DB, Visual Studio 2017. 使用ASP.NET MVC,.NET Framework 4.5.2,用于SQL DB的实体数据模型,Visual Studio 2017。

I have a class generated from the ADO.NET(EF Designer from Database) : 我有一个从ADO.NET(数据库的EF设计器)生成的类:

BookInfo.cs 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; }
}
}

The database is designed where the "BookID" in the BookInfo table has a foreign key "BookID" in the Inventory table. 设计数据库时,BookInfo表中的“ BookID”在库存表中具有外键“ BookID”。 In a view to update an inventory's properties referenced by "BookID", I then proceed to query the list and update the correct instance. 为了更新“ BookID”所引用的库存的属性,我接着继续查询列表并更新正确的实例。

Screenshot of update inventory page: 更新清单页面的屏幕截图:

在此处输入图片说明

When landing on page to enter info the [HttpGet] UpdateInventory() is called, when clicking "Create" button as seen above, the [HttpPost] UpdateInventory(...) is called. 当登陆页面输入信息时,将调用[HttpGet] UpdateInventory(),如上图所示,单击“创建”按钮时,将调用[HttpPost] UpdateInventory(...)。

Logic/Code in Controller: 控制器中的逻辑/代码:

    [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 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.
    }

The Null Exception Thrown: 抛出Null异常:

在此处输入图片说明

Code for all.cshtml view page: 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 }))

your view is throwing error because you are returning the view without passing the model, you are using return View("All") without passing the model the right way is by passing the model with the view, you can do it this way View("ViewName", ModelData); 您的视图抛出错误,因为您在不通过模型的情况下返回视图,在不通过模型的情况下使用return View("All") ,正确的方式是通过将模型与视图一起通过,您可以通过View("ViewName", ModelData);

in your case 在你的情况下

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

for the saving part I am not sure why, but i can see few errors, first what if book does not have inventory info ? 对于节省部分,我不确定为什么,但是我能看到的错误很少,首先,如果书籍没有库存信息该怎么办? it will throw null error, so first check if null, create new inventory, if not update accordingly here is how i would do it 它将引发null错误,因此首先检查是否为null,创建新的广告资源,如果没有进行相应的更新,这就是我的方法

 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();

}

As a first step , put the breakpoint in the getAllBooksInfo method and see whether the list count is coming or not in visual studio. 第一步,将断点放在getAllBooksInfo方法中,然后查看列表计数是否在Visual Studio中出现。 This will help you a lot. 这将对您有很大帮助。

And As an alternative step, you can also solve this error by using the ToPagedList(pageIndex, pageSize); 并且作为替代步骤,您也可以通过使用ToPagedList(pageIndex,pageSize);来解决此错误。 method, i have used it personally and it was worked well 方法,我个人使用过,效果很好

ToPagedList example as per your code: 根据您的代码的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.
        }**

official source: https://github.com/troygoode/PagedList 官方资料来源: https //github.com/troygoode/PagedList

Note: Even with this approach, kindly check whether you are getting the data or not from the database by using the breakpoint in the changed line. 注意:即使采用这种方法,也请使用更改后的行中的断点检查是否从数据库中获取数据。

Hope this will surely solve your problem kindly let me know thoughts or feedbacks 希望这一定能解决您的问题,请让我知道您的想法或反馈

Thanks 谢谢

karthik KARTHIK

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM