XsltListViewWebParts with Paging problem or SaveChanges error

Let’s imagine, that we want to have SharePoint Library Template with more than 90 Views.

We want to define this views inside of List Schema.xml file because this is the easiest way for fast provisioning of SharePoint lists and their views. But there is the limit – List definition in Schema.xml file could contains max 90 views!

So we have to choose another way – we could define this views “by code”. We could make just few common views by Schema.xml and other could be copied from them with list.SaveAsNewView() function from SharePoint SSOM and then we could modify it by code.

After that we want to add this list views to some pages at SharePoint. Default views, made inside of Schema.xml could be added to page “by xml” with XsltListViewWebPart where we have to define BaseViewID for each view.

But views, created “by code” could be added into pages “by code” too. And here we could have problems with some SharePoint versions.

So we could programatically define our XsltListViewWebPart like this example below.

SPFile file = web.GetFile(listPages.RootFolder.ServerRelativeUrl + "/" + tipStrani + i + ".aspx");

if (file.CheckOutType == SPFile.SPCheckOutType.None)
	file.CheckOut();

using (SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
{
	XsltListViewWebPart listViewWebPart = new XsltListViewWebPart();
	listViewWebPart.ListId = list.ID;
	listViewWebPart.ListName = list.ID.ToString("B").ToUpper();
	listViewWebPart.Title = name;
	listViewWebPart.ClientRender = true;
	listViewWebPart.Toolbar = "Standard";

	listViewWebPart.ViewId = int.Parse(nView.BaseViewID);
	listViewWebPart.ViewGuid = nView.ID.ToString("B");

	webPartManager.AddWebPart(listViewWebPart, "Main2Top", 0);
}

file.Update();
file.CheckIn("");
file.Publish("");

This code work perfectly when you have view without paging (paged == false). In case where you want to have paging, paging only work for first page of your list view web part. So when you go to the second page, paging buttons / pager disappear.

On the internet you could find answer for that issue inside of SaveChanges() command.

So now our modified code could look like this below:

SPFile file = web.GetFile(listPages.RootFolder.ServerRelativeUrl + "/" + tipStrani + i + ".aspx");

if (file.CheckOutType == SPFile.SPCheckOutType.None)
	file.CheckOut();

using (SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
{
	XsltListViewWebPart listViewWebPart = new XsltListViewWebPart();
	listViewWebPart.ListId = list.ID;
	listViewWebPart.ListName = list.ID.ToString("B").ToUpper();
	listViewWebPart.Title = name;
	listViewWebPart.ClientRender = true;
	listViewWebPart.Toolbar = "Standard";

	listViewWebPart.ViewId = int.Parse(nView.BaseViewID);
	listViewWebPart.ViewGuid = nView.ID.ToString("B");

	webPartManager.AddWebPart(listViewWebPart, "Main2Top", 0);
	webPartManager.SaveChanges(listViewWebPart);
}

file.Update();
file.CheckIn("");
file.Publish("");

But from SharePoint 2013 SP1 you get an exception on command webPartManager.SaveChanges(listViewWebPart) like this below -> Object reference not set to an instance of an object:

Here you could read discussion about that.

So if we use SaveChanges() command we got an exception, if we don’t use it, pager is gone.

As you could see in the exception above, the problem is in view -> EnsureView couldn’t get specific view. So the problem could be SSOM caching related.

I solve this problem with first example of code above (without SaveChanges() command) + code below which runs after all web parts are added to page and page is updated, checked-in and published:

SPFile file = web.GetFile(listPages.RootFolder.ServerRelativeUrl + "/" + tipStrani + i + ".aspx");

if (file.CheckOutType == SPFile.SPCheckOutType.None)
	file.CheckOut();

using (SPLimitedWebPartManager wpmgr = file.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
{
	foreach (System.Web.UI.WebControls.WebParts.WebPart wpInstance in wpmgr.WebParts)
	{
		if (wpInstance.GetType() == typeof(XsltListViewWebPart))
		{
			wpmgr.SaveChanges(wpInstance);
		}
	}
}

file.Update();

file.CheckIn("");
file.Publish("");

Thats all.

Happy coding folks!

Cheers!
Gašper Rupnik

{End.}

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by WordPress.com.

Up ↑

%d bloggers like this: