Unable to acces lists cross site collection using Linq To SharePoint

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

  • Friday, January 08, 2010 12:11 PM
     
      Has Code
    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.

All Replies

  • Friday, January 08, 2010 6:08 PM
     
     
    Permissions?
  • Saturday, January 09, 2010 11:06 AM
     
     
    Nop,

    The account that I am using is over the 3 site collections, site collection admin.
  • Monday, January 11, 2010 8:35 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 18, 2010 3:00 PM
     
     
    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,
    Pascal
  • Tuesday, January 19, 2010 9:45 AM
     
      Has Code

    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
     
     Answered Has Code

    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

  • Friday, February 04, 2011 10:25 AM
     
     
  • Friday, April 01, 2011 2:39 AM
     
     
    Thanks Pascal,  it works for me :)
    regards, Sudhir Kesharwani
  • Friday, April 13, 2012 5:42 AM
     
     
    Thanks Pascal ...... it really helped.. 

    Kunal Valecha

  • Tuesday, May 15, 2012 5:30 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.

  • Thursday, November 29, 2012 10:54 PM
     
     
    Thanks Pascal, this helped me a lot