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

SharePoint Architect, Developer, Technical Trainer, Microsoft MVP (Office Development). Above 15 years of total experience working with SharePoint, Dynamics CRM, Office 365, and Microsoft stack development.

You May Also Like

Linq to Sharepoint. Part 1

Linq to Sharepoint. Part 1

Linq to SharePoint. Part 2

Linq to SharePoint. Part 2

Linq to SharePoint. Part 4

Linq to SharePoint. Part 4

Linq to SharePoint. Part 5. Choice and MultiChoice fields

Linq to SharePoint. Part 5. Choice and MultiChoice fields

Linq to SharePoint vs Camlex.NET Performance Comparison

Linq to SharePoint vs Camlex.NET Performance Comparison