Consolidating data in SharePoint from different sites based on variable site naming - sharepoint

am working on a project where I want to pull data from different lists in SharePoint and have these data imported into a single list. The list has the same attribute everywhere; it is located in different sites.
I have a list which contains all the site names and URL to those sites. The idea is to read from this list all the site names and then go to each one of those sites and try and pull the information from the list under that particular site, in synchronies matter. Data that are pulled from last week’s process do not need to be pulled again.
Can someone guide me in explaining what would be the best way to doing this solution?
Am using SharePoint 2007

You may be better off looking at the Data View Web Part (DVWP) and rollups
A common topic that is asked about in
SharePoint, is how to roll up
information from sub-sites to a top
level site, and just generally how to
show data from one site on another
site.

I have this scenario. I made a webpart that sends the information for my consolidation list, through the sharepoint web services.
I installed the webpart in each sharepoint site, this webpart get the data (when it's outdated) and make a insert in the consolidation list through the lists.asmx webservice. See http://msdn.microsoft.com/en-us/library/lists(v=office.12).aspx. Then a I create a user with permission to write in the consolidation list in my consolidation site, and used this to authenticate my webpart when it will do the insert on the list.
I did something like this, in Visual Studio 2005, with Sharepoint dll referenced.
public void InsertToPainel(string strID, string user, string password)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
try
{
//WSPainel is the WebReference to http://<site>/_vti_bin/Lists.asmx.
using (WSPainel.Lists lstPainel = new webPartSender.WSPainel.Lists())
{
lstPainel.UseDefaultCredentials = true;
lstPainel.Credentials = new System.Net.NetworkCredential(user, password);
#region Make the fields in consolidation list
Dictionary<string, string> fieldsNamesAndValues = new Dictionary<string, string>();
fieldsNamesAndValues.Add("ID", strID);//Recuperar quando for atualizar ou incluir New
fieldsNamesAndValues.Add("URL", SPContext.Current.Web.Url + ", " + splInfGerItems[0]["Title"].ToString()); //The link of the actual site that is sending the information
fieldsNamesAndValues.Add("Comments", splStatusItems[0]["Title"].ToString());//In my case, I just need the last result.
#endregion
//It will make the register in CAML format and updates the lists.
lstPainel.UpdateListItems(_listaPainel, NewCAMLRegister(fieldsNamesAndValues, strID));
}
}
catch (Exception e)
{
//Exception
}
});
}
private XmlNode NewCAMLRegister(Dictionary<string, string> FieldsNamesAndValues, string strID)
{
try
{
XmlDocument xdMensagem = new XmlDocument();
XmlElement xeBatch = xdMensagem.CreateElement("Batch");
XmlNode xnMethod = xdMensagem.CreateElement("Method");
xdMensagem.AppendChild(xeBatch);
xeBatch.AppendChild(xnMethod);
XmlAttribute xaID = xdMensagem.CreateAttribute("ID");
XmlAttribute xaCmd = xdMensagem.CreateAttribute("Cmd");
xaID.Value = "1"; //Id do comando no Batch.
if (strID == "New")
{
xaCmd.Value = "New";
}
else
{
xaCmd.Value = "Update";
}
xnMethod.Attributes.Append(xaID);
xnMethod.Attributes.Append(xaCmd);
foreach (KeyValuePair<string, string> strfieldname in FieldsNamesAndValues)
{
XmlNode xnField = xdMensagem.CreateElement("Field");
XmlAttribute xaName = xdMensagem.CreateAttribute("Name");
xaName.Value = strfieldname.Key;//Nome do Campo
xnField.Attributes.Append(xaName);
xnField.InnerText = strfieldname.Value;//Valor do Campo
xnMethod.AppendChild(xnField);
}
//"<Method ID=\"1\" Cmd=\"New\">" + "<Field Name=\"ID\">New</Field>" + "<Field Name=\"Title\">This is a test</Field>" + "</Method>";
return xdMensagem;
}
catch (Exception e)
{
//Exception
return null;
}
}
I hope it helps.

Related

Custom Filter Web Part to filter/update ListView Web Part

Scenario : I need Refresh/Filter the Items/records displayed in List View Web Part on the same page based on selected filters. So I created Visual Web Part and tried to modify the View of List View Web Part Programmatically. So far i have reached till here :
string spListName = "Job";
protected void BtnSearchClick(object sender, EventArgs e)
{
try
{
SPWeb oWebsite = SPContext.Current.Web;
SPList oList = oWebsite.Lists[spListName];
XsltListViewWebPart xsltWP = null;
SPWebPartManager wpManager = WebPartManager.GetCurrentWebPartManager(Page) as SPWebPartManager;
//Code to Find List View Web Part on Page
foreach (System.Web.UI.WebControls.WebParts.WebPart wp in wpManager.WebParts)
{
if (wp.GetType().Name == "XsltListViewWebPart")
xsltWP = wp as XsltListViewWebPart;
}
oWebsite.AllowUnsafeUpdates = true;
StringBuilder strbPreQuery = new StringBuilder("<Where><Eq>");
StringBuilder strbPostQuery = new StringBuilder("</Value></Eq></Where>");
string strQueryKeyword = "<FieldRef Name='Customer' /><Value Type='Lookup'>";
SPQuery oQuery = new SPQuery();
oQuery.Query = strbPreQuery.ToString() + strQueryKeyword + txtCustomer.Text + strbPostQuery.ToString();
SPListItemCollection itemCol = oWebsite.Lists[spListName].GetItems(oQuery);
PropertyInfo pi = xsltWP.GetType().GetProperty("ContextView", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
SPView view = (SPView)(pi.GetValue(xsltWP, null));
view.Query = oQuery.Query;
view.Update();
wpManager.SaveChanges(xsltWP);
xsltWP.DataBind();
oWebsite.AllowUnsafeUpdates = false;
}
catch (Exception ex)
{
Response.Write(ex);
}
}
The Above code works but now I am facing following problems :
The results updation requires page refresh so If I add following code, results are updated but filter values in visual web part is lost.
this.Context.Response.Redirect(this.Context.Request.Url.ToString());
Filtered applied by one user is also reflected to another user.
Can some please help in to address these two problems I have ? that is I want
To preserve the filter values and results to be modified at the same time
The filtering should be only for one user and not for all.
Any help in this regards will be appreciated.
Create a SPQuery that will hold the default value of the view.
then after passing the value,
Use this to revert back the default query of the view.
SPView _view;
protected void Page_Unload(object sender, EventArgs e)
{
//your code
SPView view = (SPView)(pi.GetValue(xsltWP, null));
view.Query = _view.Query;
view.Update();
}

Creating Document set programatically in sharepoint 2010

I am creating a document set programatically on buttom click event
public void btnCreateDocumentSet_Click(object sender, EventArgs e)
{
try
{
lblError.Text = string.Empty;
SPSecurity.RunWithElevatedPrivileges(() =>
{
using (web = SPControl.GetContextSite(Context).RootWeb)
{
web.AllowUnsafeUpdates = true;
String url = web.Lists[" Tracker"].RootFolder.ServerRelativeUrl.ToString();
SPList list = web.Lists["Tracker"];
Hashtable props = new Hashtable();
props.Add("Number", "item1");
props.Add("Type", "item2");
DocumentSet ds = DocumentSet.Create(list.RootFolder, "NewDocumentSet3", web.ContentTypes["MydocumentSet2"].Id, props, true);
//test
//web.Dispose();
}
}
);
}
catch (SPException ex)
{
lblError.Text = ex.Message;
}
}
I am not getting any exceptions.On button click i am redirected to an error like the following
However the document set named NewDocumentSet3 is created in document library but it looks like a folder(the icon i mean) . when i go to document library->documents tab->New Document I am not getting the document set type .Kindly advise me on this issue.
Thanks in advance
First of all, turn off custom errors, like the screenshots tells you.
Then replace your catch of SPException with a catch of all Exceptions.
Even better yet, test code like this in a separate console app, not right inside handlers.
Look up some resources on the internet on how to debug SharePoint applications. A breakpoint will get you a long way in this particluar situation.
I am very wary of your list called "[space]Tracker". Looks suspicious to me.
Try adding
props.Add("HTML_x0020_File_x0020_Type", "SharePoint.DocumentSet");
to the properties hashset that gest passed in to DocumentSet.Create method.

Retrieve all Master Pages for a SharePoint Site?

How can I determine programmatically what master pages (custom and OOTB) that are available for to use for a web site in SharePoint?
Thanks, MagicAndi
I came up with this solution, making use of a SPQuery object to query the team site collection's Master Page Gallery list:
try
{
using (SPSite site = new SPSite(this.ParentSiteUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList myList = web.Lists["Master Page Gallery"];
SPQuery oQuery = new SPQuery();
oQuery.Query = string.Format("<Where><Contains><FieldRef Name=\"FileLeafRef\" /><Value Type=\"File\">.master</Value></Contains></Where><OrderBy><FieldRef Name=\"FileLeafRef\" /></OrderBy>");
SPListItemCollection colListItems = myList.GetItems(oQuery);
foreach (SPListItem currentItem in colListItems)
{
// Process master pages
}
}
}
}
catch (Exception ex)
{
}
Use reflection and check whether the type's base type equals System.Web.UI.MasterPage.
So something along the lines of:
foreach(Type t in Assembly.GetExecutingAssembly().GetTypes())
{
if (t.BaseType==typeof(MasterPage))
{
// do something, add to collection - whatever
}
}
But, depending on in what assembly your MasterPages are defined, and the fact it iterates over all the types in a specific assembly, it may definitely not be the best solution.
I am blissfully ignorant about SharePoint, but this solution is somewhat more generic I guess.

How to access the Sharepoint SPNavigationNode.QuickLaunch Property?

I have a site as follows:
--SiteA
----Subsite1
----Subsite2
Now whenever i try to access the QuickLaunch Property its always empty e.g
SPNavigation nav = spWeb.Navigation;
if (nav.QuickLaunch.Count == 0)
{
// ALWAYS TRUE
}
However if i go into the Naviation Settings (Through the UI) of SiteA and reorder any site in the list, only then will the QuickLanuch become available. (Other settings are left as default)
Can anyone explain this behaviour? I really need access to the QuickLaunch items.
Thanks
This error occurs if you access quicklaunch while site is being created.Below code causes the feature activated code to wait until the site collection has been created before executing.
using System.Threading;
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//Queues changes until after site exists. For use in provisioning.
SPWeb web = properties.Feature.Parent as SPWeb;
ThreadPool.QueueUserWorkItem(ApplyYourChanges, web.Url);
}
private void ApplyYourChanges(object state)
{
string webUrl = state as string;
Uri uri = new Uri(webUrl);
// additional conditions here -- perhaps check if a feature was activated
while (!SPSite.Exists(uri))
{
Thread.Sleep(5000);
}
using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
//configure the quicklaunch menu
configureQuickLaunch(web);
}
}
}
public static void configureQuickLaunch(SPWeb spWeb)
{
SPNavigationNodeCollection nodeCollection = spWeb.Navigation.QuickLaunch;
SPNavigationNode heading = nodeCollection.Cast<SPNavigationNode>().FirstOrDefault(n => n.Title == headingNode);
SPNavigationNode item = heading.Children.Cast<SPNavigationNode>().FirstOrDefault(n => n.Url == url);
if(item == null)
{
item = new SPNavigationNode(nodeName, url);
item = heading.Children.AddAsLast(item);
}
}
I think, by default, the QuickLaunch uses shared navigation. In other words, the QuickLaunch for a subsite doesn't have its own collection of nodes until you do something with it. If you reorder a site, that gives it its own unique set of nodes.
If you wanted to programmatically set your QuickLaunch to have its own set of nodes programmatically, you should be able to do so this way:
SPNavigation nav = spWeb.Navigation;
nav.UseShared = false;
spWeb.Update();
I think your count should be something other than zero at that point.
I seem to remember reading somewhere that the QuickLaunch collection only stored customisations to the default ordering. Looking around, I can't find that documentation to show you, but it would explain the behavior you see if true.
So your QuickLaunch.Count == 0 is just confirming that default ordering of items is in place.
You can still add nodes, if that's at all helpful;
SPNavigationNodeCollection nodes = web.Navigation.QuickLaunch;
SPNavigationNode node = new SPNavigationNode("Node Name", "Node URL", true);
nodes.AddAsFirst(node);

Find out the URL for the document library of a SharePoint document

If i know the URL for a document, can I find the URL for sharepoint document library in which the document is present. The following are two sample URLs for a SharePoint site. The first document is present under the root of a document library. The second document is present under a folder "folder1" within the document library. Appreciate if there is anyway to know the URL for a document library (http:///sites/site1/DocLib/Forms/AllItems.aspx).
http:///sites/site1/DocLib/a.doc
http:///sites/site1/DocLib/folder1/a.doc
Thanks for your replies. I am looking for a solution with MOSS OOTB web service or based on the URL pattern. Can we use any of these to acheive this please?
Thanks.
The SPWeb object has a GetFile method, which takes the full file url.
SPFile file = web.GetFile(yoururl);
Now it's easy to get to the SPList's url, by using the following:
string listUrl = file.Item.ParentList.DefaultViewUrl;
So, in a method together:
public string GetListUrlFromFileUrl(string fullFileUrl)
{
using (SPSite site = new SPSite(fullFileUrl))
{
using(SPWeb myWeb = site.OpenWeb())
{
SPFile file = myWeb.GetFile(fullFileUrl);
return file.Item.ParentList.DefaultViewUrl;
}
}
}
Make sure to reference Microsoft.Sharepoint.dll in your project as well.
There are two different ways I do this, depending on the situation. Neither performs extremely well (important to note), though the second solution typically performs fairly well for our use cases.
The first is extremely simple:
private SPList GetListForFile(string fileUrl)
{
using (SPSite site = new SPSite(fileUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPFile file = web.GetFile(fileUrl);
if (file.Exists)
{
return file.Item.ParentList;
}
}
}
return null;
}
The second is a little more complex. It does require you first chopping off the file part of the URL, then passing it in to the method to get the correct SPWeb, then finding the right list in the web.
private SPList GetListForFile(string fileUrl)
{
using(SPWeb web = OpenWeb(GetFolderUrl(fileUrl)))
{
string listName = fileUrl.Replace(web.ServerRelativeUrl, "");
listName = listName.Substring(0, listName.IndexOf('/'));
return web.Lists[listName];
}
}
private string GetFolderUrl(string fileUrl)
{
return Regex.Replace(fileUrl, #"/[^/]+?\.[A-Z0-9_]{1,6}$", "",
RegexOptions.IgnoreCase | RegexOptions.Singleline);
}
private SPWeb OpenWeb(string folderUrl)
{
SPWeb web = null;
while(web == null)
{
web = Site.OpenWeb(folderUrl);
if (!web.Exists)
{
web.Dispose();
web = null;
}
folderUrl = folderUrl.Substring(0, folderUrl.LastIndexOf("/"));
if (folderUrl.Length == 0)
{
folderUrl = "/";
}
}
return web;
}

Resources