2

This code is from a sequential workflow. I am trying to grab the most recent item in a document library. I check to make sure there are more than zero items in the library, then I try to grab the most recent. However, when I try this, I get an "Object reference not set to an instance of an object." error. I have used this exact same code in other places for different document libraries and it works just fine. I can call the library, get an ItemCount from it, but I can't grab any of the items. Could there be some special permission or lock on this document library that I don't know about?

        if (tlList.ItemCount > 0)
        {
            SPListItem item = tlList.Items[tlList.ItemCount - 1];

            name = item["Name"].ToString();
            user = item["Modified By"].ToString();
            url = SharepointState.siteUrl + "/" + SharepointState.TLLibraryName + "/" + DocumentState.TrackingNumber.Replace(':', '_');
            itemNumber = (ulong)DateTime.Now.Ticks;
        }

Edit: I just found some code in the Feature Event Receiver that also calls on tlList and does it successfully. Here is the code:

            tlList = SharepointState.Web.Lists.TryGetList(SharepointState.TLLibraryName);
            SharepointState.Web.AllowUnsafeUpdates = true;
            SPList workflowhistory = SharepointState.Web.Lists["Workflow History"];
            SPList tasks = SharepointState.Web.Lists["Tasks"];

            SPWorkflowAssociation spas = null;
            spas = SPWorkflowAssociation.CreateListAssociation(baseTemplate, "NSI_FCS_Workflow", tasks, workflowhistory);
            spas.AutoStartCreate = true;
            spas.AutoStartChange = true;
            tlList.WorkflowAssociations.Add(spas);
            tlList.Update();
            SharepointState.Web.AllowUnsafeUpdates = false;

Perhaps I need to 'dispose' of the document library before trying to grab it again when the workflow starts? Perhaps I am doing something to the document library in this code that is preventing me from accessing it again in the future? Let me know if you have any suggestions.

2
  • I assume you are getting the obj ref error at 'SPListItem item'? Commented Jun 8, 2011 at 19:08
  • Correct, at the SPList item Commented Jun 9, 2011 at 3:45

4 Answers 4

1

Are you able to step through the code? In the immediate window, when within your If statement, enter tlList.ItemCount, and see it's value. Then enter tlList.Items.Count. The ItemCount property is stored as a separate field in the ContentDB, but that should never differ from the actual items list.

1
  • When I try tlList.Items.Count I the same error "Object reference not set to an instance of an object." but tlList.ItemCount works just fine. Commented Jun 9, 2011 at 16:41
1

Most likely the problem is because you're using tlList.ItemCount -1 as the index to retrieve your SPListItem. I don't think you can ever assume this is the ID number of the last item your library. For example, deleting items will result in a lower item count.

Instead, I would probably use a CAML query with SPQuery and SPQuery.RowLimit = 1:

<OrderBy><FieldRef Ascending="False" Name="Created" /></OrderBy>
1
  • In debug mode, when I look at the tlList properties, almost every single field has a "NullReferenceException" in it. The only one that has an actual value is ItemCount Commented Jun 9, 2011 at 17:46
1

If you have folders in your document library, your count will be off. Read the Community Content at the bottom of this MSDN page.

SPList.ItemCount returns the total items in the list/doc lib including folders.

But, SPList.Items.Count only returns the individual items.

4
  • There are no folders in the document library. I have even tried to grab item[0] or item[1] also with no luck Commented Jun 9, 2011 at 16:45
  • If there are checked out documents, this will also cause ItemCount to be higher than Items.Count. As @Kit Menke pointed out, you cannot depend on the ItemCount's being the same as Items.Count, so you should create the query and use SPListItemCollection items = tList.GetItems(query); name = items[0]["Name"].ToString();
    – Laurie
    Commented Jun 9, 2011 at 17:16
  • I just tried this and received the same warning. My code looked like: SPQuery q = new SPQuery(); q.RowLimit = 1; q.Query = "<OrderBy><FieldRef Ascending='False' Name='Name' /></OrderBy>"; SPListItemCollection col = tlLibrary.GetItems(q); string name = col[0]["Name"].ToString(); Name is a field in the document library Commented Jun 9, 2011 at 17:44
  • I'm not sure how you could get the same error, if you are removing the line of code on which you were getting the error. You need to remove the line: SPListItem item = tlList.Items[tlList.ItemCount - 1]; Also, if you want the latest item, you should sort by created date: SPQuery q = new SPQuery(); q.RowLimit = 1; q.Query = "<OrderBy><FieldRef Ascending='False' Name='Created' /></OrderBy>"; SPListItemCollection col = tlLibrary.GetItems(q); string name = col[0]["Name"].ToString();
    – Laurie
    Commented Jun 9, 2011 at 18:17
0

Well I made a total 'newb' mistake. I didn't initialize my SPSite or my siteCollection.OpenWeb objects, which was preventing me from properly accessing the document library. Here is the final code that worked:

        using (SPSite siteCollection = new SPSite(SharepointState.siteUrl))
        {
            SPWeb web = siteCollection.OpenWeb();

            SPDocumentLibrary tlLibrary = (SPDocumentLibrary)web.Lists[SharepointState.TLLibraryName];

            //populate some of the class's fields before starting
            if (tlLibrary.ItemCount > 0)
            {
                SPListItem item = tlLibrary.Items[tlLibrary.ItemCount - 1];

                trackingNumber = item["Name"].ToString();
                user = item["Modified By"].ToString();
                url = SharepointState.siteUrl + "/" + SharepointState.TLLibraryName + "/" + DocumentState.TrackingNumber.Replace(':', '_');
                //use the current datetime in ticks to generate a unique number for the MessageSequenceNumber field in the SAR form    
                itemNumber = (ulong)DateTime.Now.Ticks;
            }
        }
2
  • Make sure to add a using statement around your OpenWeb() so that the SPWeb object is disposed of properly.
    – Laurie
    Commented Jun 9, 2011 at 20:28
  • Also, if all you access is the site collection's root site, use RootWeb instead of OpenWeb(), this is less prone to memory leak errors. This object is managed by sharepoint so don't dispose it!
    – Colin
    Commented Jun 9, 2011 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.