Second Life of a Hungarian SharePoint Geek

March 15, 2008

Negative item count in document libraries

Filed under: Bugs, SharePoint — Tags: , — Peter Holpar @ 00:59

Note: This is a repost, the original one was published on SharePoint Blogs on March 15 , 2008

A few days ago we received a complaint from one of our customers. They found that after deleting all documents from it, a SharePoint document library that serves as the base of a custom application shows negative item count on the All Site Content page.

NegItemCount1_thumb1

We checked where this value comes from and found it is the ItemCount property of the SPList object.

An additional side effect of this strange behavior is that the indexing fails because it cannot cast the negative value to an unsigned integer (UInt32).

NegItemCount2_thumb1

We could reproduce the behavior using the following code. It assumes that the address of your site is your site is http://moss/site and the name of the document library is CopyTest. The code creates a folder and subfolders, copies it using the CopyTo() method of SPFolder class, and finally deletes the folders.

 

string siteUrl = "http://moss/site";

using (SPSite site = new 

SPSite(siteUrl))

{

 using (_web = site.OpenWeb())

 

{

 SPList list = 

_web.Lists["CopyTest"];

 

Console.WriteLine("Items.Count:{0}, ItemCount:{1}", list.Items.Count, 

list.ItemCount);

 Console.WriteLine("Creating 1.0 folder 

... ");

 SPFolder rootFolder = 

_web.GetFolder("/CopyTest");

 SPFolder version1Folder = 

rootFolder.SubFolders.Add("/CopyTest/1.0");

 

version1Folder.Update();

 

list.Update();

 

Console.WriteLine("OK");

 

Console.WriteLine("Items.Count:{0}, ItemCount:{1}", list.Items.Count, 

list.ItemCount);

 Console.WriteLine("Creating Test1 in 1.0 

folder ... ");

 SPFolder testFolder = 

version1Folder.SubFolders.Add(version1Folder.Url + 

"/Test1");

 testFolder.Update();

 

list.Update();

 

Console.WriteLine("OK");

 Console.WriteLine("Items.Count: 

{0}", list.Items.Count);

 Console.WriteLine("ItemCount: 

{0}", list.ItemCount);

 Console.WriteLine("Creating Test1.1 

in Test1 folder ... ");

 SPFolder test2Folder = 

version1Folder.SubFolders.Add(version1Folder.Url + 

"/Test1/Test1.1");

 

test2Folder.Update();

 list.Update();

 

Console.WriteLine("OK");

 Console.WriteLine("Items.Count: 

{0}", list.Items.Count);

 Console.WriteLine("ItemCount: 

{0}", list.ItemCount);

 Console.WriteLine("Creating Test2 

in 1.0 folder ... ");

 SPFolder test3Folder = 

version1Folder.SubFolders.Add(version1Folder.Url + 

"/Test2");

 test3Folder.Update();

 

list.Update();

 

Console.WriteLine("OK");

 Console.WriteLine("Items.Count: 

{0}", list.Items.Count);

 Console.WriteLine("ItemCount: 

{0}", list.ItemCount);

 Console.WriteLine("Creating 2.0 

folder in the root ... ");

 SPFolder version2Folder = 

rootFolder.SubFolders.Add("/CopyTest/2.0");

 

version2Folder.Update();

 

list.Update();

 

Console.WriteLine("OK");

 

Console.WriteLine("Items.Count:{0}, ItemCount:{1}", list.Items.Count, 

list.ItemCount);

 Console.WriteLine("Copy 1.0 items to 

2.0");

 foreach (SPFolder subFolder in 

version1Folder.SubFolders)

 

{

 Console.WriteLine("Copy {0} folder ... ", 

subFolder.Name);

 

subFolder.CopyTo(version2Folder.Url + "/" + 

subFolder.Name);

 SPFolder folder = 

_web.GetFolder(version2Folder.Url + "/" + 

subFolder.Name);

 

if(folder.Exists)

 

Console.WriteLine("Folder exists, url is: {0}", 

folder.ServerRelativeUrl);

 

folder.Update();

 

list.Update();

 

Console.WriteLine("OK");

 

Console.WriteLine("Items.Count:{0}, ItemCount:{1}", list.Items.Count, 

list.ItemCount);

 }

 

Console.WriteLine("Deleting 1.0 folder ... ");

 SPFolder 

deleteFolder = _web.GetFolder("/CopyTest/1.0");

 if 

(deleteFolder.Exists)

 {

 

deleteFolder.Delete();

 

list.Update();

 

Console.WriteLine("OK");

 }

 

Console.WriteLine("Deleting 2.0 folder ... ");

 

deleteFolder = _web.GetFolder("/CopyTest/2.0");

 if 

(deleteFolder.Exists)

 {

 

deleteFolder.Delete();

 

list.Update();

 

Console.WriteLine("OK");

 }

 

Console.WriteLine("SPList.ItemCount = {0}", list.ItemCount);

 }

} 

We escalated the issue to MS support and waiting for a resolution now.

I should note that there is an interesting blog post about the relation of SPList.ItemCount and SPList.Items.Count here. The main point is that if the number of items is changed (for example, by deleting or creating items) in the document libraries, then the value stored in the ItemCount does not changed until SPList.Update() is called. You should be aware of this behavior in your custom applications.

Update: After about a year of mailing we got the response from the support that the behavior wouldn’t be fixed in this version, since it is too complex.

March 4, 2008

Using Month element in DateRangesOverlap can return items not in the specified month

Filed under: Calendar, CAML, SharePoint — Tags: , , — Peter Holpar @ 23:02

One can logically think that if you set the CalendarDate property of the SPQuery and apply Month as the Value in the DateRangesOverlap element then the query returns items from the month specified in the CalendarDate property.

For example, using the following code …

SPQuery query = new SPQuery();
query.CalendarDate = new DateTime(2008, 3, 1);

… and applying the following CAML query …

<Where>
<DateRangesOverlap>
<FieldRef Name='StartDate' />
<FieldRef Name='EndDate' />
<Value Type='DateTime'>
<Month />
</Value>
</DateRangesOverlap>
</Where>

… one can expect that items having overlap with March 2008 will be only returned.

I’ve found that it is not exactly so, as elements from the end of February and beginning of April may be also returned. The reason for that I think is the simple fact that these items have overlap with the calendar range of the month view of March 2008 (e.g. 24/02/2008-05/04/2008), as the month calendar view includes the full weeks at the beginning and the end of the month, not only the days between 01/03/2008-31/03/2008.

Since DateRangesOverlap is (another) under-documented element of SharePoint and CAML I can’t decide if it is a bug or a feature. Since it is used primarily in the calendar views it seems to be logical that it should return all items that need to be displayed in the month view. So it is probably by design, sad that this fact is not documented.

This fact caused a misbehavior (or let’s call it bug) in one of our custom application, so we should return to our original complex CAML query assembled from Lt, Gt, Leq, Geq, composite And and Or elements…

Theme: Shocking Blue Green. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 42 other followers