Answered by:
Unable to acces lists cross site collection using Linq To SharePoint

Question
-
I'm currently developing a 2010 webpart project, where I query 3 lists on 3 different site collections.
I query these list from a webpart that is located on the root site collection: http://portaltest
Site col 1: http://portaldev/sites/site1 - list x
Site col 2: http://portaldev/sites/site2 - list y
Site col 3: http://portaldev/sites/site2 - list z
When I try to access list x on the site collection: http://portaldev/sites/site1 (from a webpart on the root site collection http://portaldev)
I receive an ArgumentException: {"Web at http://portaldev/sites/site1 could not be found"}
The code that I am using is the folowing
using (LinqDataContext ctx = new LinqDataContext("http://portaldev/sites/site1")) { EntityList<listx> entities = ctx.GetList<listx>("listx"); }
But when I try to run the same webpart on a web of http://portaldev/sites/site1, the code will run an I'm able to query the list x.- Edited by Stefaan Van Autgaerden Friday, January 8, 2010 12:13 PM formatting
Friday, January 8, 2010 12:11 PM
Answers
-
We have found a workaround by changing the SPContext before executing the LINQ query.
In the webpart itself the HttpContext is stored in a variable before executing our search method.
SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite contextSite = new SPSite("http://<URL>")) { using (SPWeb contextWeb = contextSite.OpenWeb()) { HttpRequest httpRequest = new HttpRequest("", contextWeb.Url, ""); HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter())); SPControl.SetContextWeb(HttpContext.Current, contextWeb); using (MyLinqDataContext dc = new MyLinqDataContext("http://<URL>")) { EntityList<MyEntity> entities = dc.GetList<MyEntity>("<ListName>"); { } } } } }
After performing the search we set the HttpContext back to the original HttpContext.
tempContext = HttpContext.Current; this.Search(); HttpContext.Current = tempContext;
I'm not sure if this workaround is appropriate, but at least we can now perform our cross site collection LINQ query in our webpart :)Regards,
Pascal- Marked as answer by Stefaan Van Autgaerden Thursday, January 21, 2010 9:38 AM
- Unmarked as answer by Stefaan Van Autgaerden Thursday, January 21, 2010 9:38 AM
- Proposed as answer by Pascal Be Thursday, January 21, 2010 9:39 AM
- Marked as answer by Stefaan Van Autgaerden Friday, January 22, 2010 6:29 PM
Tuesday, January 19, 2010 3:43 PM
All replies
-
Permissions?Friday, January 8, 2010 6:08 PM
-
Nop,
The account that I am using is over the 3 site collections, site collection admin.Saturday, January 9, 2010 11:06 AM -
We even tested the code using a console application. In a console application there no problem, but when we use it in a webpart it throws the error.Monday, January 11, 2010 8:35 AM
-
Does anyone else has the same problem ?
The code works perfectly on a console application one the Sharepoint server but doesn't work in a webpart.
Regards,
PascalMonday, January 18, 2010 3:00 PM -
We have found the cause of this problem. When an SPContext is available (like in the webpart), the constructor of SPServerDataConnection tries the open the url in the SPSite of the context.
So querying a linq datasource in a different site collection doesn't work whenever an SPContext object is available.
We managed to reproduce this problem in our console application by createing a fake SPContext object which causes the same error.
Microsoft.Sharepoint.Linq.Provider - SPServerDataConnection:public SPServerDataConnection(string url) { if (SPContext.Current != null) { this.defaultSite = SPContext.Current.Site; this.defaultWeb = (SPContext.Current.Web.Url == url) ? SPContext.Current.Web : this.defaultSite.OpenWeb(new Uri(url).PathAndQuery); } else { this.defaultSite = new SPSite(url); this.defaultWeb = this.defaultSite.OpenWeb(new Uri(url).PathAndQuery); } if (!this.defaultWeb.Exists) { throw new ArgumentException(Resources.GetString("CannotFindWeb", new object[] { url })); } this.defaultWebUrl = this.defaultWeb.ServerRelativeUrl; this.openedWebs = new Dictionary<string, SPWeb>(); this.openedWebs.Add(this.defaultWebUrl, this.defaultWeb); }
Is there anyone from Microsoft that can confirm if this behaviour is by design or a bug.
Regards,
PascalTuesday, January 19, 2010 9:45 AM -
We have found a workaround by changing the SPContext before executing the LINQ query.
In the webpart itself the HttpContext is stored in a variable before executing our search method.
SPSecurity.RunWithElevatedPrivileges(delegate() { using (SPSite contextSite = new SPSite("http://<URL>")) { using (SPWeb contextWeb = contextSite.OpenWeb()) { HttpRequest httpRequest = new HttpRequest("", contextWeb.Url, ""); HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter())); SPControl.SetContextWeb(HttpContext.Current, contextWeb); using (MyLinqDataContext dc = new MyLinqDataContext("http://<URL>")) { EntityList<MyEntity> entities = dc.GetList<MyEntity>("<ListName>"); { } } } } }
After performing the search we set the HttpContext back to the original HttpContext.
tempContext = HttpContext.Current; this.Search(); HttpContext.Current = tempContext;
I'm not sure if this workaround is appropriate, but at least we can now perform our cross site collection LINQ query in our webpart :)Regards,
Pascal- Marked as answer by Stefaan Van Autgaerden Thursday, January 21, 2010 9:38 AM
- Unmarked as answer by Stefaan Van Autgaerden Thursday, January 21, 2010 9:38 AM
- Proposed as answer by Pascal Be Thursday, January 21, 2010 9:39 AM
- Marked as answer by Stefaan Van Autgaerden Friday, January 22, 2010 6:29 PM
Tuesday, January 19, 2010 3:43 PM -
Easy solution:
http://blog.lekman.com/2010/08/using-linq-to-sharepoint-between-site.html
Thanks to Tobias
Friday, February 4, 2011 10:25 AM -
Thanks Pascal, it works for me :)
regards, Sudhir KesharwaniFriday, April 1, 2011 2:39 AM -
Thanks Pascal ...... it really helped..
Kunal Valecha
Friday, April 13, 2012 5:42 AM -
Just use the constructore of context and every thing will work fine.
using (LinqDataContext context = new LinqDataContext('WebPath'))
{
}
i tried this many times before.Tuesday, May 15, 2012 5:30 AM -
Thanks Pascal, this helped me a lotThursday, November 29, 2012 10:54 PM
-
You can also use the crossSiteCollection flag when creating the DataContext ( see http://msdn.microsoft.com/en-us/library/jj835494.aspx).
Although SPMetal does not provide this constructor by default it is simple enough to add:
namespace spmetal { public partial class LinqDataContext: Microsoft.SharePoint.Linq.DataContext { public LinqDataContext(string requestUrl, bool crossSiteCollection) : base(requestUrl, crossSiteCollection) { this.OnCreated(); } } }
Then when you create the LinqDataContext and pass true for crossSiteCollection you wont need to change the HttpContext.- Edited by Ryan.Erickson4 Tuesday, June 11, 2013 10:53 PM
Tuesday, June 11, 2013 10:53 PM