Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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.

share|improve this question
    
I assume you are getting the obj ref error at 'SPListItem item'? –  Tim Gabrhel Jun 8 '11 at 19:08
    
Correct, at the SPList item –  Meyer Denney Jun 9 '11 at 3:45
add comment

4 Answers 4

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.

share|improve this answer
    
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. –  Meyer Denney Jun 9 '11 at 16:41
add comment

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>
share|improve this answer
    
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 –  Meyer Denney Jun 9 '11 at 17:46
add comment

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.

share|improve this answer
    
There are no folders in the document library. I have even tried to grab item[0] or item[1] also with no luck –  Meyer Denney Jun 9 '11 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 Jun 9 '11 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 –  Meyer Denney Jun 9 '11 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 Jun 9 '11 at 18:17
add comment
up vote 0 down vote accepted

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;
            }
        }
share|improve this answer
    
Make sure to add a using statement around your OpenWeb() so that the SPWeb object is disposed of properly. –  Laurie Jun 9 '11 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 Jun 9 '11 at 21:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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