6

I have a list of SPWeb IDs and would like to open the associated SPWeb objects. However, I do not know in which Site Collection they are (I DO know that they are in the current Web Application though).

Is there a good (fast!) way to do so, or will I need to have the Site Collection ID in any case?

3
  • Need to understand the context.. are you planning to do something one time only? using PowerShell? Commented Dec 5, 2011 at 20:36
  • @Ashish No, it's for a web part that has to access a bunch of SPWebs. Currently I only have a List<Guid> with the SPWeb.ID, but now I need to do this cross-Site collection and wonder if I can avoid changing the data structure to also have the Site Collection ID. Commented Dec 5, 2011 at 21:32
  • My current algorithm goes through all Site Collections and Webs to find it, which is obviously slow, so I want to optimize it, preferably without changing the underlying data. Commented Dec 5, 2011 at 21:33

4 Answers 4

4

You can use the full URL to the web. When getting an SPWeb you have two options: 1) us the SPSite and parse through the Webs -or- 2) look it up by the full URL to the web.

1
3

I just ran into the same problem and I figured out that you can pass the entire URL into the constructor of SPSite and it will determine which portion of the url is the site collection. Here is my code snippet I used in a method where I am trying to seperate the string into the site collection url and the relative site path.

   try
   {
   //these local variables are created because an out or ref variable cannot be 
   //accessed inside SPSecuirty.RunWithElevatedPrivileges
   string siteCollectionPath = "";
   string relativeSitePath = "";
   SPSecurity.RunWithElevatedPrivileges(delegate()
   {
   using (SPSite spSite = new SPSite(fullPath))
   {
   relativeSitePath = fullPath.Replace(spSite.Url, "").TrimStart('/');
   using (SPWeb spWeb = spSite.AllWebs[relativeSitePath])
   {
   siteCollectionPath = spSite.Url;
   }
   }
   });
   siteCollectionUrl = siteCollectionPath;
   relativeSiteUrl = relativeSitePath;
   }
   catch (FileNotFoundException ex)
   {
   //the path does not point to a site collection
   }
   catch (UriFormatException ex)
   {
   //the path does not point to a site collection
   }
   catch (ArgumentException ex)
   { 
   //the relativeSitePath was invalid
   }
2
  • When you pass http://server/subsite to SPSite, then calling OpenWeb() will be in the context of /subsite. No need to go to AllWebs, which could be slow to enumerate if there are thousands.
    – James Love
    Commented Mar 18, 2015 at 18:35
  • Also, unless your code absolutely has to run as the Application Pool service account, then call new SPSite(fullPath, SPUserToken.SystemAccount) instead, without the SPSecurity.RunWithElevatedPrivileges
    – James Love
    Commented Mar 18, 2015 at 18:39
1

if you are in a web context and you know that your webs are in the current app, all you can is to loop through all site collections and try opening all your IDs on each SPSite object. Although please note that I would avoid holding more than one SPSite and SPWeb object in a time so it make sense to process your Webs and remove them from the list right after that. Not so quick process in any case. Possible workaround is to use LongRunningOperation for it (MS SPLRO sample)

Other possible approach is to use Search but I not sure how to do it that way

0

Ended up changing my data so that I have both the Web and Site ID.

2
  • 5
    I wouldn't call this the "answer" to your problem. If anything I would've edited and/or closed your question.
    – user4545
    Commented Dec 20, 2011 at 1:35
  • 1
    well, it is actually good enough answer but from architecture perspective instead of development one :) I would vote up just for thinking ootb Commented Sep 8, 2012 at 7:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.