Pages

Friday, March 8, 2013

LINQ to SharePoint, RunWithElevatedPrivileges, and Anonymous Users

The LINQ data context class that you generate using SPMetal will not work if you try to access a list from this class which is not publicly accessible. This issue is explained really well in the following article and is very helpful in the scenarios when you need to access a list from pages that doesn’t require users to login such as login or sign-in pages. The workaround is to tweak your code to use HttpContext instead of SPContext which generally runs under the current user account. This is explained in the following article.

http://blogs.msdn.com/b/sowmyancs/archive/2010/09/19/linq-to-sharepoint-and-runwithelevatedprivileges.aspx

 

I am providing the code from this site for reference here:

using System;
 
using System.ComponentModel;
 
using System.Web;
 
using System.Web.UI;
 
using System.Web.UI.WebControls;
 
using System.Web.UI.WebControls.WebParts;
 
using Microsoft.SharePoint;
 
using Microsoft.SharePoint.WebControls;
 
using Microsoft.SharePoint.Linq;
 
using System.Collections.Generic;
 
using System.Linq;
 
 
 
namespace LinqWebPart.WebPart1
{
 
    [ToolboxItemAttribute(false)]
 
    public class WebPart1 : WebPart
    {
 
        protected override void CreateChildControls()
        {
 
            string strUrl = SPContext.Current.Web.Url;
 
            HttpContext backupCtxt = HttpContext.Current;
 
            try
            {
 
                // if there is a SPContext make it is as null so LINQ won’t execute under current context
 
                if (SPContext.Current != null)
 
                    HttpContext.Current = null;
 
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
 
                    using (SPSite oSite = new SPSite(strUrl))
                    {
 
                        using (SPWeb oWeb = oSite.OpenWeb())
                        {
 
                            // creating a new HttpContext under elevated permission and setting it as current control context web, because of this the code will be running under elevated permission.
 
                            HttpRequest httpRequest = new HttpRequest("", oWeb.Url, "");
 
                            HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new System.IO.StringWriter()));
 
                            SPControl.SetContextWeb(HttpContext.Current, oWeb);
 
                            using (DemositeDataContext dc = new DemositeDataContext(oWeb.Url))
                            {
 
                                var q = from list in dc.Announcements
 
                                        where list.Title == "My Announcment title"
 
                                        orderby list.Id
 
                                        select new { DisplayName = list.Title };
 
 
 
                                //remaining code goes here...
 
                            }
 
                        }
 
                    }
 
                }
 
               );
 
            }
 
            catch (Exception ex)
            {
 
                //Use your favourite form of logging to log the error message and exception ....            
 
            }
 
            finally
            {
 
                // make sure that you are setting the actual SPContext back after your operation and make SharePoint happy J
 
                if (SPContext.Current != null)
 
                    HttpContext.Current = backupCtxt;
 
            }
 
        }
 
    }
 
}

No comments:

Post a Comment