简体   繁体   中英

C# I'm trying to create a web user control with custom classes, and I am getting a Object not set to an instance of an Object Error

I hope you can help me with this. I am creating an internal webforms asp.net site to display a list of internally used documents in different categories.

I decided to create a custom document class to put in a list to hold the documents, and then a custom web user control to display the documents wherever they want them on the site.

The documents class is in a general class file in my App_Code folder.

cab.net.cs

public class Document
{
    private string _Url;
    private string _Title;
    public Document(string URL, string Title)
    {
        _Url = URL;
        _Title = Title;
    }

    public string URL
    {
        get { return _Url; }
        set { _Url = value; }
    }

    public string Title
    {
        get { return _Title; }
        set { _Title = value; }
    }
}

This code works just fine. Then in my user control I create a list of type document and initiate it in Page_Load(). Then I created a public method to add new documents to the list.

DocDisplay.ascx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class DocDisplay : System.Web.UI.UserControl
{
    private List<Document> _DocList;

    protected void Page_Load(object sender, EventArgs e)
    {
        _DocList = new List<Document>();
    }

    public void Add(string URL, string Title)
    {
        _DocList.Add(new Document(URL, Title));
    }

    public void WriteDocuments()
    {
        foreach (Document doc in _DocList)
        {
            Response.Write($"<span class='document'><a href='{doc.URL}'>{doc.Title}</a></span>");
        }
    }
}

I am getting the error in the add method. It says that my object is not to an instance of an object. But I do that in Page_Load.

index.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    pageDocs.Add("index.aspx", "Hello World!");
    pageDocs.Add("index.aspx", "Red Rum");
    pageDocs.Add("index.aspx", "Lorum Ipsum");
}

I have registered my user control in my index page.

<%@ Register Src="~/DocDisplay.ascx" TagPrefix="uc" TagName="DocDisplay" %>

<uc:DocDisplay ID="pageDocs" runat="server" />

So I am not exactly sure why I am getting that error. As far as I can tell, there is nothing wrong with my code. If you could help I would greatly appreciate it.

Events get fired starting from the root of control hierarchy and end at the leaf nodes. Index.Page_Load is being called before DocDisplay.Page_Load has an opportunity to instantiate the list.

The _DocList field needs a value before it can be used by anything, so initialization needs to happen as early as possible. This is accomplished very easily with a field initializer. Declare and assign it all at once:

private List<Document> _DocList = new List<Document>();

When the Index class instantiates its child controls early in the page life cycle, _DocList will immediately have an object reference.

It's tempting to say, "Page_Init will be called sooner; I'll do it there." This may work at first, but if you do any dynamic control loading, you'll soon find out that it's a balancing act. A dynamically loaded control has to play event catch-up, so its Init event can be fired after statically loaded controls have started firing Load events. It's important to use each event for its purpose, and not for its timing, and use constructors (and field initializers) to initialize non-control class state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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