I have the problem where a user has created a view and I need to get access to it and make it public. I appreciate this is quite a slog, especially in an ideal world the user would make the List public but if he/she has left …
The first problem was identifying the information for the view. After quite a bit of digging I find it in the WebParts table in the appropriate Content Database
Health and Safety warning – do not play with this data, there are some rather large and ugly dragons who are not scared to bite you, which in turn could incur the wrath of you superiors.
The field you are after is tp_view this contains a pseudo xml file showing the view.
To progress further I created a winform application with a textbox and a button, the string from tp_view goes in to the textbox. The button_click performs the magic.
We are going to use the splist.Views.Add function
Code Snippet
- SPView view = list.Views.Add("newView", strCollViewFields, strQuery, uint.Parse(RowLimit), true, false);
All of the information above is found in the string.
strCollViewFields is populated using, which is relatively straight forward the +13 means we get the end tag as well
Code Snippet
- private StringCollection GetViewFields()
- {
- XmlDocument xmlDoc = new XmlDocument();
-
- //assumes Viewfields is at the beginning of the string.
- string xml = definition.Substring(0, definition.IndexOf("</ViewFields>") + 13);
- xmlDoc.LoadXml(xml);
-
- var returnvar = new StringCollection();
-
- foreach (XmlNode node in xmlDoc.SelectNodes("ViewFields/FieldRef"))
- {
- returnvar.Add(node.Attributes[0].Value);
- }
-
- return returnvar;
- }
strQuery, here I +7 is on the start tag because I do not want the Query tag, this is a SharePoint thing and I do not know why!
Code Snippet
- private string GetQuery()
- {
- string returnVar = string.Empty;
-
- int queryTagStartLocation = definition.IndexOf("<query>", StringComparison.InvariantCultureIgnoreCase) + 7;
- int queryTagEndLocation = definition.IndexOf("</query>", StringComparison.InvariantCultureIgnoreCase);
- int queryLength = queryTagEndLocation - queryTagStartLocation;
- //All we need is the contents not the actual query tag
- returnVar = definition.Substring(queryTagStartLocation, queryLength);
-
- return returnVar;
- }
RowLimit and Paged ( I have set it to true above)
Code Snippet
- private string GetRowLimit(out bool Paged)
- {
- //<RowLimit Paged="TRUE">100</RowLimit>
-
- string value = string.Empty;
- string paged = string.Empty;
-
- XmlDocument xmlDoc = new XmlDocument();
- xmlDoc.LoadXml(GetXMLString("RowLimit"));
-
- foreach (XmlNode node in xmlDoc.SelectNodes("RowLimit"))
- {
- paged = node.Attributes[0].Value;
- value = node.InnerXml;
- }
-
- Paged = bool.Parse(paged);
-
- return value;
- }
Here I have created a new function GetXMLString() which I am sure you could parameterise and deprecate GetQuery()
Code Snippet
- private string GetXMLString(string tag )
- {
- string startTag = "<" + tag ;
- string endTag = "</" + tag + ">";
-
-
- int queryTagStartLocation = definition.IndexOf(startTag, StringComparison.InvariantCultureIgnoreCase);
- int queryTagEndLocation = definition.IndexOf(endTag, StringComparison.InvariantCultureIgnoreCase) + endTag.Length;
- int queryLength = queryTagEndLocation - queryTagStartLocation;
- //All we need is the contents not the actual query tag
- return definition.Substring(queryTagStartLocation, queryLength);
- }
The List I had also has some aggregations which we can get from GetXMLString() function.
All in all the main function looks like this
Code Snippet
- try
- {
- definition = textBox1.Text;
-
- bool paged;
- var strCollViewFields = GetViewFields();
- var strQuery = GetQuery();
- var RowLimit = GetRowLimit(out paged);
- var aggregations = GetXMLString("Aggregations"); ;
-
- SPSecurity.RunWithElevatedPrivileges(delegate()
- {
-
- using (var site = new SPSite("http://srvJupiter:6000/"))
- {
- using (var web = site.AllWebs[0])
- {
-
- var list = web.Lists["Projects"];
-
- SPView view = list.Views.Add("newView", strCollViewFields, strQuery, uint.Parse(RowLimit), true, false);
-
- view.Aggregations = aggregations;
- view.Update();
-
- }
- }
- }
- );
As usual test anything in a test system first.