Unable to acces lists cross site collection using Linq To SharePoint
-
Friday, January 08, 2010 12:11 PM
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 08, 2010 12:13 PM formatting
Answers
-
Tuesday, January 19, 2010 3:43 PM
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
All Replies
-
Friday, January 08, 2010 6:08 PMPermissions?
-
Saturday, January 09, 2010 11:06 AMNop,
The account that I am using is over the 3 site collections, site collection admin. -
Monday, January 11, 2010 8:35 AMWe 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 18, 2010 3:00 PMDoes 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,
Pascal -
Tuesday, January 19, 2010 9:45 AM
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,
Pascal -
Tuesday, January 19, 2010 3:43 PM
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
-
Friday, February 04, 2011 10:25 AM
Easy solution:
http://blog.lekman.com/2010/08/using-linq-to-sharepoint-between-site.html
Thanks to Tobias
-
Friday, April 01, 2011 2:39 AMThanks Pascal, it works for me :)
regards, Sudhir Kesharwani -
Friday, April 13, 2012 5:42 AMThanks Pascal ...... it really helped..
Kunal Valecha
-
Tuesday, May 15, 2012 5:30 AMJust use the constructore of context and every thing will work fine.
using (LinqDataContext context = new LinqDataContext('WebPath'))
{
}
i tried this many times before.