簡體   English   中英

如何使用 EF Core 3.1.5 解決 ASP.net Core 應用程序中的 null 引用異常?

[英]How can I resolve null reference exception in ASP.net Core application using EF Core 3.1.5?

當我將以下內容添加到客戶端詳細信息視圖時,我收到了 null 引用異常:

<dt>
    @Html.DisplayNameFor(model => model.Contacts)
</dt>
<dd>
    <table class="table">
        <tr>
            <th>FN</th>
            <th>LN</th>
            <th>Email</th>
            <th>Contact Type</th>
        </tr>
        @foreach (var item in Model.Contacts)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.FN)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.LN)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Email)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ContactType)
                </td>
            </tr>
        }
    </table>
</dd>

為什么我在@Html.DisplayNameFor(model => model.Contacts)處收到 null 參考異常,我該如何解決?

以下是Client class 刪除了數據注釋以便於閱讀:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace scms_core.Models
{
    public class Client
    {        
        public int Id { get; set; }
        public string CrtdBy { get; set; }        
        public DateTime CrtdDt { get; set; }
        public string FN { get; set; }
        public string LN { get; set; }
        public string BN { get; set; }

        public int ClientTypeId { get; set; }
        public tlClientType ClientType { get; set; }

        public virtual ICollection<Contact> Contacts { get; set; }
    }
}

以下是Contact class,也去掉了數據注釋以便於閱讀:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace scms_core.Models
{
    public class Contact
    {
        public int Id { get; set; }
        public string CrtdBy { get; set; }
        public DateTime CrtdDt { get; set; }
        public string FN { get; set; }
        public string LN { get; set; }
        public string Email { get; set; }

        public int ContactTypeId { get; set; }
        public tlContactType ContactType { get; set; }

        public int ClientId { get; set; }
        public virtual Client Client { get; set; }
    }
}

當我刪除應該獲取聯系信息的代碼的引用時,詳細信息頁面將起作用。 當我將此代碼添加到視圖時,它只是失敗了。 以下是客戶詳細信息視圖:

@model scms_core.Models.Client

@{
    ViewData["Title"] = "Details";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Details</h1>

<div>
    <h4>Client</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.CrtdBy)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.CrtdBy)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.CrtdDt)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.CrtdDt)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.FN)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.FN)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.LN)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.LN)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.BN)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.BN)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.ClientType)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.ClientType.ClientType)
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Contacts)
        </dt>
        <dd>
            <table class="table">
                <tr>
                    <th>FN</th>
                    <th>LN</th>
                    <th>Email</th>
                    <th>Contact Type</th>
                </tr>
                @foreach (var item in Model.Contacts)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.FN)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.LN)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Email)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.ContactType)
                        </td>
                    </tr>
                }
            </table>
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

下面是 controller 代碼:

public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var client = await _context.Clients
            .Include(c => c.ClientType)
            .FirstOrDefaultAsync(m => m.Id == id);

        if (client == null)
        {
            return NotFound();
        }

        return View(client);
    }

您應該像這樣在客戶端 model 構造函數中初始化聯系人集合

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace scms_core.Models
{
  public class Client
  {        
    public Client()
    {
       Contacts = new HashSet<Contact>();
    }

    public int Id { get; set; }
    public string CrtdBy { get; set; }        
    public DateTime CrtdDt { get; set; }
    public string FN { get; set; }
    public string LN { get; set; }
    public string BN { get; set; }

    public int ClientTypeId { get; set; }
    public tlClientType ClientType { get; set; }

    public virtual ICollection<Contact> Contacts { get; set; }
}

}

應該是這樣,將Id更改為ClientID並制作一個[Key][Table]您想要擁有主鍵並制作表格的地方:

[Table("Client")]
public class Client
    {        
        [Key]
        public int ClientID { get; set; }
        public string CrtdBy { get; set; }        
        public DateTime CrtdDt { get; set; }
        public string FN { get; set; }
        public string LN { get; set; }
        public string BN { get; set; }    
        public int ClientTypeID { get; set; }
        [ForeignKey("ClientTypeID")]
        public ClientType ClientType { get; set; }
        public int ContactID { get; set; }
        [ForeignKey("ContactID")]
        public virtual Contact Contact { get; set; }   

        public ICollection<Contact> Contacts { get; set; }
    }

Id更改為ContactID

[Table("Contact")]
public class Contact
    {
        [Key]
        public int ContactID { get; set; }
        public string CrtdBy { get; set; }
        public DateTime CrtdDt { get; set; }
        public string FN { get; set; }
        public string LN { get; set; }
        public string Email { get; set; }
        public int ContactTypeID { get; set; }
        [ForeignKey("ContactTypeID")]
        public virtual ContactType ContactType { get; set; }
        public int ClientID { get; set; }
        [ForeignKey("ClientID")]
        public virtual Client Client { get; set; }
    }

您的 controller 應該聲明一個列表並將視圖 model 發送到 razor 頁面。 應該看起來像這樣:

public async Task<ActionResult> Contacts()
    {
        var allClients = await _context.Clients.ToList();

        List<Contact> viewModel = allClients.Select(x => new Contacts
        {
            FN = x.FN,
            LN = x.LN,
            Email = x.Email,
            ContactType = x.ContactType
        }).ToList();


        return View(viewModel);
    }

您應該對將要創建數據庫的所有模型執行相同的操作。 在您的聯系人頁面中,您沒有提及您正在使用哪個@model ,但它應該看起來像這樣: @model List<YourProject.UI.Models.Contacts>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM