Aug 20

Imagine: your site is in production and you need to add a new custom SPView to an existing SPList. SharePoint gives you only the possibility to use SPViewCollection.Add but this method ghosts the given view. Why don't I want to let it ghosted? – Only for maintenance reason. The next time you will upgrade your WSP solution or just overwrite your view file (say 12\FEATURES\MyFeature\MyList\customview.aspx), it will remains unchanged because the actual view is ghosted inside the database, and thus, with no relation with the physical file.

Maybe you are curious why creating your own custom SPView? Here is some real life examples :

  • A "flat tree" view (see picture1), supporting folder reorder, renaming, creation, …
  • A chart view
  • An embedded Flash/Silverlight application
  • A SPGridView with custom columns and/or filter
  • A jQuery photo gallery ;-)
  • Or any business related view of your imagination…

  Picture1

 

There is really no way to override that ghosting behavior and abusing SharePoint with some Reflection hacks doesn't help!
But you can still look inside the database after the creation of the view. Open up SQL Server Management Studio and take a look in the database. (If you don't know how to open the SharePoint database, use this database name: \\.\pipe\mssql$microsoft##ssee\sql\query).

In your WSS_Content database, you should retrieve all the metadatas of your lists, webparts, ghosted aspx file, … in the AllDocs table.

The SetupPath column is what you are seeking: the relative path to your code file, but for the moment, it is NULL. Let's update it with a simple SQL query

 

 

My helper code:

CreateCustomView(list, "Flat tree", "Flatten", @"Features\NFSiteFeature\FolderList\Flatten.aspx");


…

private static void CreateCustomView(SPList list, String viewName, String pageName, String setupPath)
{
	// If the view already exists, leave
	try
	{
		if (list.Views[viewName] != null) return;
	}
	catch (ArgumentException)
	{
		// does not exists !
	}

	SPView view = list.Views.Add(pageName, new StringCollection(), String.Empty, 100, false,
		 false, SPViewCollection.SPViewType.Html, false);

	try
	{
		using (SqlConnection connection = new SqlConnection("Data Source=localhost;Initial Catalog=WSS_Content;Integrated Security=True"))
		{
			SqlCommand cmd = connection.CreateCommand();
			cmd.CommandText = @"UPDATE AllDocs SET SetupPath = @SetupPath WHERE LeafName = @ViewName AND ListId = @ListId";

			cmd.Parameters.Add("@SetupPath", System.Data.SqlDbType.NVarChar, 255).Value = setupPath;
			cmd.Parameters.Add("@ViewName", System.Data.SqlDbType.NVarChar, 128).Value = pageName + ".aspx";
			cmd.Parameters.Add("@ListId", System.Data.SqlDbType.UniqueIdentifier).Value = list.ID;

			connection.Open();
			int rc = cmd.ExecuteNonQuery();

			cmd.Dispose();
		}
	}
	catch (SqlException exc)
	{
		Console.WriteLine("An Sql exception occured while updating view '{0}' from list '{1}':\n{2}",
			pageName, list.RootFolder.ServerRelativeUrl, exc.Message);
		hasError = true;
	}

	view.Title = viewName;
	view.Update();
}

That'is it Laughing

Tags:

Comments

get educated

Posted on Friday, 30 October 2009 06:05

There is really no way to override that ghosting behavior and abusing SharePoint with some Reflection hacks doesn't help!

Olivier

Posted on Friday, 30 October 2009 07:29

You looks like you don't read the first paragraph. I explain why unghosting files...

Jerry

Posted on Wednesday, 24 March 2010 02:43

I agree with the comment that this should not be done like this. Working with SharePoint Database like this is totally unsupported and unrealistic. It is not an offence OK but we may have done this by a web part.

Still useful information.

The lifewave

Posted on Saturday, 29 May 2010 05:50

Very interesting review...you have done an excelent work analizing SPView

Comments are closed