Walkaround for problems accessing a diffrent web by “Linq to SharePoint” inside server code.

At the weekend I tried to access a diffrent SharePoint Web (SPWeb) from inside server code (ASPX application page).

Before I created interface classes to the “diffrent SharePoint Web” by using SPMetal.

In the server side code I used this snipped to access the “diffrent SharePoint Web” by using the generated interface:

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace myProject
{
public partial class ManageFeature : LayoutsPageBase
{
protected void Page_Load(object sender, EventArgs e)
{

string diffrentWebUrl = “http://diffrentWebUrl”;
using( DiffrentWebDataContext dc = new DiffrentWebDataContext(diffrentWebUrl) )
{
var x1 = from x in dc.ListOnDiffrentWeb
                             select x;
var x2 = x1.ToList();
}
}
}
}

This failed because inside server code you cannot access a diffrent Web by using Linq to SharePoint.

Read this blog post Chun Liu:

http://blogs.msdn.com/b/chunliu/archive/2010/04/17/linq-to-sharepoint-query-across-site-collections.aspx

Here is a suggestion how to solve this by Pascal Be:

http://social.technet.microsoft.com/Forums/sv-SE/sharepoint2010programming/thread/715ddcbb-619d-4688-8d99-d7a6aa078307

I’ve created a helper class for this workaround:

using System;
using System.IO;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace ik.SharePoint2010
{
    public class CustomSPContext : IDisposable {
        private HttpContext originalContext;

        public static CustomSPContext CreateSPCustomContext(SPWeb contextWeb)
        {
            return new CustomSPContext(contextWeb);
        }

        private CustomSPContext(SPWeb contextWeb)
        {
            originalContext = HttpContext.Current;

            string url = contextWeb.Url;
            HttpRequest httpRequest = new HttpRequest("", url, "");
            HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));
            SPControl.SetContextWeb(HttpContext.Current, contextWeb);
        }

        public void Dispose()
        {
            HttpContext.Current = originalContext;
        }
    }
}

 

You can use it like this:

using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace kc.GlobalNotification
{
    public partial class ManageFeature : LayoutsPageBase {
        protected void Page_Load(object sender, EventArgs e)
        {
            string diffrentWebUrl = "http://diffrentWebUrl";

            using( var site = new SPSite(diffrentWebUrl) )
            {
                using( var web = new SPWeb(diffrentWebUrl) )
                {
                    using( ik.SharePoint2010.CustomSPContext.CreateSPCustomContext(web) )
                    {

using( DiffrentWebDataContext dc = new DiffrentWebDataContext(diffrentWebUrl) ){

                           var x1 = from x in dc.ListOnDiffrentWeb
                                    select x;
                           var x2 = x1.ToList();

}

                    }
                }
            }
        }
    }
}