Upgrading SharePoint - Some views not upgraded to XsltListViewWebPart


Update 24/08/16

Revisited post: http://www.sharepointblogs.be/blogs/vandest/archive/2016/08/24/revisited-upgrading-sharepoint-some-views-not-upgraded-to-xsltlistviewwebpart.aspx

Update 16/07/13

Included the tool and source for SharePoint 2013 and expanded functionality so that you can specify the entire Web Application, Site Collection or Site. See below for links.

Issue

One issue you might see when upgrading your content to a newer version of SharePoint is that not all views in SharePoint Lists and Libraries are upgraded.

What I’ve seen on multiple occasions is that some views aren’t upgraded. You can most easily spot them because there are no (multiselect) checkboxes on that view, even if you check “Tabular view” in the view settings.

Furthermore, if you append ?contents=1 to the URL you’ll see that the legacy ListViewWebPart class is used, rather than the new XsltListViewWebPart class.

image

Checkboxes missing:

Posts

Checkboxes present:

Comments

Manual fix

A manual fix would be to edit the page, go to the Web Part properties and just save without making any modifications. This seems to convert the legacy Web Part to the newer equivalent.

This would require quite some effort if you have many libraries of course.

Automated fix

I’ve been trying to reproduce the mechanism used by the manual fix described above, but not dice. The best I came up with is cloning the SPView and deleting the original one.

The base of the application will loop an entire Site Collection, through all sites, lists and views that match the prerequisite “IsLegacyWebPart”.

using (SPSite site = new SPSite(url))
{
    // All webs in site collection
    site.AllWebs.Cast<SPWeb>().ForEach(w =>
        {
            using (SPWeb web = w)
            {
                // All lists in web
                web.Lists.Cast<SPList>().ToList().ForEach(l =>
                {
                    // All legacy views
                    l.Views.Cast<SPView>().ToList().Where(v => v.IsLegacyWebPart()).ForEach(v => v.Recreate());
                });
            }
        });
}

The “IsLegacyWebPart” check is an extension method that looks up the Web Part bound to the given SPView. If this is the legacy ListViewWebPart it will return true. I have yet to find a more optimized way of detecting a ‘legacy’ view.

public static bool IsLegacyWebPart(this SPView view)
{
    bool result = false;

    SPList list = view.ParentList;
    SPWeb web = list.ParentWeb;
    SPFile file = web.GetFile(view.ServerRelativeUrl);

    using (MSWPP.SPLimitedWebPartManager man = file.GetLimitedWebPartManager(PersonalizationScope.Shared))
    {
        result = man.WebParts.OfType<MSWPP.ListViewWebPart>().Any();
    }

    return result;
}

Finally we have the “Recreate” algorithm for all legacy views.

public static void Recreate(this SPView view)
{
    if ((view == null) || String.IsNullOrEmpty(view.Title))
        return;

    // Init
    SPList list = view.ParentList;
    string viewName = Path.GetFileNameWithoutExtension(view.Url);
    string viewTitle = view.Title;

    // Create temporary clone
    SPView tempView = view.Clone("TEMP", "TEMP");
    view.Delete();

    // Create definite clone
    SPView newView = tempView.Clone(viewName, viewTitle);
    tempView.Delete();
}

public static void Delete(this SPView view)
{
    view.ParentList.Views.Delete(view.ID);
}

public static SPView Clone(this SPView view, string newViewName, string newViewTitle)
{
    SPView result = view.Clone(newViewName, view.RowLimit, view.Paged, view.DefaultView);
    result.Title = newViewTitle;
    result.TabularView = view.TabularView;
    result.Update();

    return result;
}

The “Recreate” extension method works with an intermediary temporary cloned view, because the view name has to be unique. If you clone a view with the same title/name it would be named “title1”.

The “Clone” method explicitly sets the “TabularView” property. I’m unaware if other properties need to be explicitly defined.

Download

I’ve wrapped it as a console application that needs to run locally on a SharePoint server. You need to run it as an account with sufficient permissions to manipulate views in the Web Application/Site Collection/Site.

Feel free to incorporate this in your application if you find it useful.

image

Note that not all hits will be solved, even with multiple runs of this tool. For example all Galleries will keep on using the ListViewWebPart. Another example are some special views on the blog site.

  • SharePoint 2010 edition (only supports Site Collections): TOOL | SOURCE CODE (Visual Studio 2010)
  • SharePoint 2013 edition (supports Web Applications, Site Collections, Sites): TOOL | SOURCE CODE (Visual Studio 2013)

Hope this helps!

 


Links to this post

Comments

Wednesday, 9 Jan 2013 08:46 by Pascal Van Vlaenderen
Nice coding style :) Very nice implementation of extension methods to make it a fluent api. Thumbs up !!

Monday, 4 Nov 2013 10:41 by Me
Thanks a lot dude!!! really helpful!!! This still helping for 2010 -> 2013 Migration!

Tuesday, 9 Dec 2014 01:16 by Andy Van Steenbergen
Very useful ;-)

Wednesday, 20 May 2015 04:02 by Sean Boltman
Great write-up and beautiful code! Definitely what I needed this moment. Thanks!!!

Friday, 15 Sep 2017 06:46 by ish1313
thanks a lot, still helpful ;)

CAPTCHA Image Validation