简体   繁体   中英

C# Recursive method returning null reference, object reference not set to an instance of an object. XElement Objects

Attempting to recursively add XElements stepping through a category list.

XElement dataResponse = new XElement("Categories",
                                       from c in db.Categories
                                       where c.CatTypeID.Equals(catTypeID) && c.ParentID.Equals(null)
                                       select new XElement("Category",
                                            c.CatID == null ? null : new XAttribute("CatID", c.CatID),
                                            c.ParentID == null ? null : new XAttribute("ParentID", c.ParentID),
                                            c.CatTitle == null ? null : new XAttribute("CatTitle", c.CatTitle),
                                            c.CatTypeID == null ? null : new XAttribute("CatTypeID", c.CatTypeID),
                                            c.shortDesc == null ? null : new XAttribute("shortDesc", c.shortDesc),
                                            c.longDesc == null ? null : new XAttribute("longDesc", c.longDesc),
                                            c.CatImage == null ? null : new XAttribute("CatImage", c.CatImage)));

                    internalData = FillSubCatagories(dataResponse).ToString();

Thats the first list of categories now i want to recursively pull all sub categories and nest them in my Xelements FillSubCatagories() method:

private XElement FillSubCatagories(XElement cat) {
        IEnumerable<XElement> list = cat.Descendants();
        int catTypeID = c.Attribute("CatTypeID") == null ? 1 : Int32.Parse(cat.Attribute("CatTypeID").Value);
        foreach (XElement c in list) {
            int parentID = Int32.Parse(cat.Attribute("CatID").Value);
            XElement sub = new XElement("sub",
                from s in db.Categories
                where s.CatTypeID.Equals(catTypeID) && s.ParentID.Equals(parentID)
                select new XElement("Category",
                     s.CatID == null ? null : new XAttribute("CatID", s.CatID),
                     s.ParentID == null ? null : new XAttribute("ParentID", s.ParentID),
                     s.CatTitle == null ? null : new XAttribute("CatTitle", s.CatTitle),
                     s.CatTypeID == null ? null : new XAttribute("CatTypeID", s.CatTypeID),
                     s.shortDesc == null ? null : new XAttribute("shortDesc", s.shortDesc),
                     s.longDesc == null ? null : new XAttribute("longDesc", s.longDesc),
                     s.CatImage == null ? null : new XAttribute("CatImage", s.CatImage)));
            c.Add(sub);
            FillSubCatagories(c);
        }
        return cat;
    }

Alright so the problem comes when I run through the foreach the second time through the method. On int parentID = Int32.Parse(cat.Attribute("CatID").Value); returns a nullreferenceException - "Object reference not set to an instance of an object"

Still getting used to c# coming from java, so be gentle. I'm sure its a glaring error but I haven't seen a clean reason why.

<<<<<<<<<>>>>>>>>>>>>>> EDITED new FillSubCategories() looks like this

private XElement FillSubCatagories(XElement cat) {
        IEnumerable<XElement> list = cat.Descendants();
        int catTypeID = cat.Attribute("CatTypeID") == null ? 1 : Int32.Parse(cat.Attribute("CatTypeID").Value);
        foreach (XElement c in list) {
            int parentID = Int32.Parse(c.Attribute("CatID").Value);
            XElement sub = new XElement("sub",
                from s in db.Categories
                where s.CatTypeID.Equals(catTypeID) && s.ParentID.Equals(parentID)
                select new XElement("Category",
                     s.CatID == null ? null : new XAttribute("CatID", s.CatID),
                     s.ParentID == null ? null : new XAttribute("ParentID", s.ParentID),
                     s.CatTitle == null ? null : new XAttribute("CatTitle", s.CatTitle),
                     s.CatTypeID == null ? null : new XAttribute("CatTypeID", s.CatTypeID),
                     s.shortDesc == null ? null : new XAttribute("shortDesc", s.shortDesc),
                     s.longDesc == null ? null : new XAttribute("longDesc", s.longDesc),
                     s.CatImage == null ? null : new XAttribute("CatImage", s.CatImage)));
            c.Add(sub);
            if (sub.Descendants() != null) {
                FillSubCatagories(sub);
            }
        }
        return cat;
    }

this got me a lot further but I still end up hitting null.

EDIT WORKING METHOD

private void FillSubCategories(XElement cat) {
        IEnumerable<XElement> list = cat.Descendants();
        foreach (XElement c in list) {
            try {
                int catTypeID = Int32.Parse(c.Attribute("CatTypeID").Value);
                int parentID = Int32.Parse(c.Attribute("CatID").Value);
                XElement sub = new XElement("sub",
                    from s in db.Categories
                    where s.CatTypeID.Equals(catTypeID) && s.ParentID.Equals(parentID)
                    select new XElement("Category",
                         s.CatID == null ? null : new XAttribute("CatID", s.CatID),
                         s.ParentID == null ? null : new XAttribute("ParentID", s.ParentID),
                         s.CatTitle == null ? null : new XAttribute("CatTitle", s.CatTitle),
                         s.CatTypeID == null ? null : new XAttribute("CatTypeID", s.CatTypeID),
                         s.shortDesc == null ? null : new XAttribute("shortDesc", s.shortDesc),
                         s.longDesc == null ? null : new XAttribute("longDesc", s.longDesc),
                         s.CatImage == null ? null : new XAttribute("CatImage", s.CatImage)));
                try {
                    string i = sub.Element("Category").Value;
                    c.Add(sub);
                    FillSubCategories(sub);
                } catch (Exception) {
                    continue;
                }
            } catch (Exception) {
                continue;
            }
        }
    }

There is no attribute "CatId" on the node specified by "cat". Maybe you've hit the top of the hierarchy?

The problem is that cat.Attribute("CatID") is null. You are doing a cat.Attribute("CatID").Value on a null gives you that error.

You could put in a check saying that if it is not null then proceed. Or was there another question?

That doesn't look good. Are you sure that there are things that are not in any category in your table? If so you shouldn't be selecting them since you are doing all the operation on the categoryId. I guess as Chris mentioned, you are getting this exception because you are on a parent category which doesn't have another parent. You need to put an if condition and not parse if it is a parent category. Something like this:

private XElement FillSubCatagories(XElement cat) {
        IEnumerable<XElement> list = cat.Descendants();
        int catTypeID = c.Attribute("CatTypeID") == null ? 1 : Int32.Parse(cat.Attribute("CatTypeID").Value);
        foreach (XElement c in list) {
        if(!String.IsNullOrEmpty(cat.Attribute("CatID").Value))
        {
            int parentID = Int32.Parse(cat.Attribute("CatID").Value);
            XElement sub = new XElement("sub",
                from s in db.Categories
                where s.CatTypeID.Equals(catTypeID) && s.ParentID.Equals(parentID)
                select new XElement("Category",
                     s.CatID == null ? null : new XAttribute("CatID", s.CatID),
                     s.ParentID == null ? null : new XAttribute("ParentID", s.ParentID),
                     s.CatTitle == null ? null : new XAttribute("CatTitle", s.CatTitle),
                     s.CatTypeID == null ? null : new XAttribute("CatTypeID", s.CatTypeID),
                     s.shortDesc == null ? null : new XAttribute("shortDesc", s.shortDesc),
                     s.longDesc == null ? null : new XAttribute("longDesc", s.longDesc),
                     s.CatImage == null ? null : new XAttribute("CatImage", s.CatImage)));
            c.Add(sub);
            FillSubCatagories(c);
            }
        }
        return cat;
    }

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