Linq to SharePoint. Part 3

Part 1. First()/FirstOrDefault(), T-SQL IN, Path
Part 2. Count(), Take(), Skip(), JOIN, ObjectTracking
Part 3. Anonymous access, Resolve list by URL
Part 4. Dynamic LINQ, Convert SPListItem to data context object
Part 5. Choice and MultiChoice fields

Resolve list by URL

There is GetList method in Microsoft.SharePoint.Linq.DataContext class used for creating custom data context. This method takes string value representing the Title of the list. And then there are two problems: what to do with localization and what to do if the list is renamed by the user.

Another pair of shoes is a list' URL: user can's change it and localization doesn't matter. But there is no method that returns a list by its URL in the SharePoint API. To resolve this trouble you can use SPWeb.GetFolder(string strUrl) method. The result of it is SPFolder object that contains ParentListId property. Following method represents this trick:

/// <summary>
/// Resolve list by URL
/// </summary>
private EntityList<T> GetListByUrl<T>(string listUrl)
{
    string listTitle;
    using(var site = new SPSite(Web))
    {
        using(var web = site.OpenWeb())
        {
            var folder = web.GetFolder(listUrl);
            var list = web.Lists[folder.ParentListId];
            listTitle = list.Title;
        }
    }
    return GetList<T>(listTitle);
}

The method is cool, but also has a limit: URL must be site relative. Like these:

"/Lists/Departments", 
"/Lists/Departments/AllItems.aspx",
"/DocLib/Forms/AllItems.aspx"

This method works some slower 'cause of initialisation of these object: SPSite, SPWeb, SPFolder and SPList.

Anonymous access

There is another trouble with user Linq to SharePoint: it can't work in anonymous access mode. The reason is this: SPContext.Current.Web.CurrentUser property in anonymous access mode is NULL. And SharePoint throws up an exception. It's enough to check out the constructor of SPServerDataConnection class (it used for retrieving data from SharePoint lists) to understand how to resolve it:

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);
}

If the current context is null it re-created using the current URL. This is the first point. The second one is that it's necessary for someone to account to impersonate it. We can use SPSecurity.RunWithElevatedPrivileges static method, which executes delegate transferred to it with full control rights. Following code executtes method with full control right if the current user is null:

public static void RunAsAdmin(SPSecurity.CodeToRunElevated secureCode)
{
    // Anonymous access flag
    var isAnonymous = SPContext.Current.Web.CurrentUser == null;
    // Is it necessary to reset current context
    var nullUserFlag = (SPContext.Current != null && isAnonymous);
 
    if (nullUserFlag)
    {
        // Save current context
        var backupCtx = HttpContext.Current;
        // Reset current context
        HttpContext.Current = null;
        // Execute code
        SPSecurity.RunWithElevatedPrivileges(secureCode);
        // Restore the context
        HttpContext.Current = backupCtx;
    }
    else
    {
        // Execute as is
        SPSecurity.RunWithElevatedPrivileges(secureCode);
    }
}

This static method may be used inside a custom data context.

That's something like this.

Vitaly Zhukov

Vitaly Zhukov

Tech Lead, Architect, Developer, Technical Trainer, Microsoft MVP. Over 20 years of experience in system integration and software development. I specialize in designing and implementing scalable, high-performance software solutions across various industries.

You May Also Like

Call Dataverse API from SPFx Web Part

Call Dataverse API from SPFx Web Part

Provision Lists and Libraries with SPFx solution

Provision Lists and Libraries with SPFx solution

SharePoint. Drag-and-Drop File Uploading

SharePoint. Drag-and-Drop File Uploading

CSOM. Upload document

CSOM. Upload document

SharePoint List REST API. Part 2

SharePoint List REST API. Part 2

SharePoint Framework. Create Angular WebPart

SharePoint Framework. Create Angular WebPart

SharePoint List REST API. Part 1

SharePoint List REST API. Part 1

Project Server. CSOM + Custom Fields

Project Server. CSOM + Custom Fields

SharePoint 2010. Long time operation with updatable status

SharePoint 2010. Long time operation with updatable status

Linq to SharePoint. Cross site collection queries

Linq to SharePoint. Cross site collection queries

SharePoint. Getting Document Icon URL

SharePoint. Getting Document Icon URL

Linq to SharePoint. Repository pattern

Linq to SharePoint. Repository pattern

Linq to SharePoint vs Camlex.NET Performance Comparison

Linq to SharePoint vs Camlex.NET Performance Comparison

Linq to SharePoint. Part 5. Choice and MultiChoice fields

Linq to SharePoint. Part 5. Choice and MultiChoice fields

Linq to SharePoint. Part 4

Linq to SharePoint. Part 4

Linq to SharePoint. Part 2

Linq to SharePoint. Part 2

Linq to Sharepoint. Part 1

Linq to Sharepoint. Part 1