LINQ to SharePoint – Obscure Workarounds

October 1 2010 177 comments

Previously I wrote about querying with SPLinq and the scope being the current site collection when running code in SharePoint. I’ve also written about using Ajax panel in web parts editor part (this post is slightly edited to serve this one). I’m going to take these two posts as basis for this post where I will speculate with workarounds available on the web to go round the two limitations of SPLinq:

  • Scope is current site collection
  • Anonymous use is not supported

Let’s make it clear at this point that I’ve not discovered the techniques to conquer SPLinq. The credit goes to these quys who have exposed the information to the web: accessing data cross site collections with SPLinq, making Linq to SharePoint work for Anonymous users, Linq to SharePoint presentation among others. Having given credits to those who deserve it, I have to also mention that I’m not too keen on the techniques and tricks. Clever they still are and I believe the only solutions to the problems. To go with what we have was my starting point this time to make some kind of a POC.

I tried to make a generalization, not being as successfull as I would have hoped to be to wrap anonymous support and cross site collection queries available to SharePoint context. This is what I came up with, a disposable object with one object to manipulate, HttpContext.Current and another object to store for the time of my disposable object’s life cycle, SPContext.Current.Web.CurrentUser:

public class ContextSwitch : IDisposable
{
    private readonly HttpContext _currentContext;
    private readonly SPUser _currentUser;
    private BlogDataContext _dataContext;
    public bool IsAnonymous
    {
        get
        {
            return _currentUser == null;
        }
    }

    public ContextSwitch()
    {
        _currentContext = HttpContext.Current;
        _currentUser = SPContext.Current.Web.CurrentUser;
        HttpContext.Current = null;
    }

    public BlogDataContext GetContext(string url)
    {
        if (IsAnonymous)
        {
            SPSecurity.RunWithElevatedPrivileges(
                    delegate { _dataContext = new BlogDataContext(url); }
                );
        }
        else
        {
            _dataContext = new BlogDataContext(url);
        }
        return _dataContext;
    }

    public void RunWithElevatedPrivileges(SPSecurity.CodeToRunElevated
        secureCode)
    {
        if (IsAnonymous)
        {
            SPSecurity.RunWithElevatedPrivileges(secureCode);
        }
    }

    public void Dispose()
    {
        _dataContext = null;
        HttpContext.Current = _currentContext;
    }
}

The idea of the above clip is to go around the condition in Microsoft.SharePoint.Linq.Provider.SPServerDataConnection by setting current httpcontext null in the constructor and setting it back to what it was in the disposer. The DataContext is also exposed via elevated privileges when used in anonymous context.

Second phase was to create the data access model with SPMetal similarly to what was described in my previous post and to extend it with custom mapping to have one more field in the queried SharePoint blog posts, the publication level of the post item.

public partial class Post : ICustomMapping
{
    public SPFileLevel PublicationLevel { get; private set; }

    [CustomMapping(Columns = new String[] { "*" })]
    public void MapFrom(object listItem)
    {
        var item = (SPListItem)listItem;
        PublicationLevel = item.Level;
    }

    public void MapTo(object listItem){}

    public void Resolve(RefreshMode mode,
        object originalListItem, object databaseListItem){}
}

The third phase would be to consume the wrapper or whatever you want to call it from a querying interface. To demonstrate, I built a similar Blog-querying model, which was also the part of the console application demonstration in my previous post:

public class BlogsDataAccess
{
    public static IEnumerable<Post> GetFromWebs(int limit,
        List<string> sources)
    {
        var posts = new List<Post>();
        if (sources == null) return posts;

        foreach (var source in sources)
        {
            var siteUrl = source.Split(';')[1];
            var webRelativeUrl = source.Split(';')[2];
            using (var site = new SPSite(siteUrl))
            {
                using (var web = site.OpenWeb(webRelativeUrl))
                {
                    if (!web.Exists) continue;
                    posts.AddRange(GetFromWeb(limit, web.Url));
                }
            }
        }
        return posts.OrderByDescending(p => p.Published).Take(limit);
    }

    public static List<Post> GetFromWeb(int limit, string webUrl)
    {
        using (var contextSwitch = new ContextSwitch())
        {
            var posts = new List<Post>();
            if (contextSwitch.IsAnonymous)
            {
                contextSwitch.RunWithElevatedPrivileges(
                    delegate
                    {
                        posts =
                        (from post in
                                contextSwitch.GetContext(webUrl).Posts
                            where post.PublicationLevel ==
                            SPFileLevel.Published
                            orderby post.Published descending
                            select post).Take(limit).ToList();
                    });
            }
            else
            {
                posts = (from post in
                                contextSwitch.GetContext(webUrl).Posts
                            where post.PublicationLevel ==
                            SPFileLevel.Published
                            orderby post.Published descending
                            select post).Take(limit).ToList();
            }
            return posts;
        }
    }
}

There is a clear problem in the clip above: running with elevated privileges. Although the query only gets published items, how can we be sure the queried sites allow anonymous access – that would be another thing to consider. My first intention was only to get the DataContext with elevated privileges but when testing, I noticed I couldn’t get the anonymous scenario to work with Blog-sites in another site collection exposed to anonymous access (403 Forbidden) whereas there were no problems retrieving posts from the current site collection – that is why the query is also executed with elevated privileges in anonymous use, not only the creation of the BlogDataContext via ContextSwitch.GetContext. Please tell me, if you find the reason for this.

Fourth phase was to include Ajax panel driven web part described in my earlier blog post to the solution to being able to test different kinds of scenarios fluently. So I added this clip to the web part’s code:

protected override void CreateChildControls()
{
    base.CreateChildControls();
    var posts = BlogsDataAccess.GetFromWebs(Limit, Webs);

    foreach (var post in posts)
    {
        Controls.Add(new LiteralControl(post.Title + "<br/><br/>"));
    }
}

And yes, it works – the web part lists blog posts from two different site collections even in anonymous use and the web part’s custom properties also work nicely with the scenario.

Am I happy to have accomplished this and would I use the solution to show information of blog posts in some public SharePoint site. Absolutely not. We have our built in content query web part – let’s stick to that. I might consider using the solution to overcome the site collection limitation if absolutely needed in a scenario where anonymous use is prohibited but I think I would feel a little nauseous.

I still haven’t overcome the explanations – or lack of them – given for the SPLinq’s scope being the current site collection. It can’t be that site colletcion should be the scope of custom queries. We’ve had our CrossListQueryCaches, SPSiteDataQueries, the search API along for some time now and with these libraries and techniques it hasn’t been a hard task to query data from another site collection. Might it have something to do with the fact that the SPLinq is a two way interface. You can also submit and delete data to and from lists with it and if some vulnerability would be exposed if there wasn’t the oddity – and oddity it is – in SPServerDataConnection’s constructor which forces the use of SPContext.Current.Site in SharePoint context, I could not say.

Popularity: 12% [?]

177 comments to “LINQ to SharePoint – Obscure Workarounds”

  1. Excellent article! We are linking to this great article on our website.

  2. Patti says:

    Awesome post.

    My web page :: Techniques of Tinnitus Miracle Exposed In This Review –
    Patti -

  3. Good site you have got here.. It’s difficult to find good quality writing like yours nowadays.
    I really appreciate people like you! Take care!!

  4. Who can say no the benefits of this lean green veggie.

    No longer can yyou bbe iin the space of negativity with your body orr you wikl continue to attract misery and paikn aand
    ariana grande weight loss before and after.
    Gymms annd recreeational fitness centers have gained a lot of popularity over the last twenty years.

  5. Common sense is your friend here: Do noot use
    capital letters in the subject line, use concise paragraphs, send messages from an address that can be answered
    still use the spelling and grammar checks efore sending an email, mass make sure
    that deadlines or special circumstances are communicated effectively, use the
    call to action words annd phrases to arouse
    interest, avoid sending images or links gadgets to try to meet as well informed of humjor or pop culture and alwahs ensure that thee
    iss an option provided by the recipient to unsubscribe ftom the mailing list.
    Depending on whhere in thee product buying cycle someone is, they
    may or may noot need certain informatkon you havfe to offer.

    My email isn’t perceived as SPAM and placed in junk
    email folders.

    Feel free to visit myy blog post: top online business degrees

  6. La centrifugeuse est quant a elle un partenaire ideal pour faire
    un jus de fruits ou de legumes ou encore un veloute.

  7. Thank you ever so for you article post.Really looking forward to read more. Much obliged.

  8. This in turn is sure to assist in enhancing the investment returns
    (ROI). Then, once published, promote them through your social media outlets to widen your audience.

    They think that a website is enough to increase leads.

  9. No2 Max says:

    I’m amazed, I must say. Rarely do I encounter a blog that’s both equally educative and amusing, and without a doubt, you
    have hit the nail on the head. The issue is something that too few men and women are speaking intelligently
    about. Now i’m very happy that I came across this during my search for something regarding
    this.

  10. Wow, that’s what I was exploring comfortis for dogs,
    what a material! existing here at this weblog, thanks admin off
    this website.

  11. cheaptshirt. says:

    My spouse and I absolutely love your blog and find the majority of your post’s to be
    exactly I’m looking for. Would you offer guest writers to
    write content to suit your needs? I wouldn’t mind writing a
    post or elaborating on a few of the subjects you write
    in relation to here. Again, awesome web log!

  12. Aw, this was a very good post. Spending some time and actual
    effort to create a very good article… but what can I say…
    I procrastinate a lot and don’t manage to get nearly anything done.

  13. Howdy I am so excited I found your website,
    I really found you by mistake, while I was looking on Google
    for something else, Regardless I am here now
    and would just like to say thanks a lot for a marvelous post and a all
    round exciting blog (I also love the theme/design), I don’t
    have time to go through it all at the minute but I have saved
    it and also included your RSS feeds, so when I have time I
    will be back to read a lot more, Please do keep up the great b.

  14. These may either be caused by the process of baking or the quality of breadmaker itself.
    As you play the game you have many different decorative items that
    become available for your farm. Everything that
    goes in your box and out the door frees up space in your home and helps out a good cause.

  15. Fitness Tips says:

    Excellent items from you, man. I’ve take into account your stuff prior to and
    you’re just too great. I really like what you’ve received right here, really like what you’re stating and the way in which
    wherein you assert it. You make it entertaining and you continue to care for
    to keep it sensible. I can not wait to read much more from you.
    This is actually a great site.

  16. Alcoholical wines for example like white or red wines, champagne otherwise spirits are generally perfectly-liked
    on business gatherings. Make sure you keep informed about any and every product you
    buy for the baby because of the fact that you may have looked
    publications and pamphlets that there are always reminders of unsafe product being
    advertised because a paper is confirmed unsafe for children and infants with what probably can be transformed into an article risky for them to manipulate or play, and watch for the new as it is made available and ensure complete
    your product registration information if needed and snail mail it in or submit
    it on the line to keep in the loop when a callback never occurs.
    To learn more about gift ideas, visit our website at My – Reviews – Now.

  17. Virgil says:

    Nice post. I learn something totally new and challenging
    on blogs I stumbleupon everyday. It’s always helpful to read through articles from other authors and use a little something from their web sites.

  18. Gladys says:

    In many cases, the supplier will likely be able to provide a
    picture of each jewelry piece, but if this is not the truth,
    just take a photo of each one as soon as you receive them.
    Valentine’s Day is the time of the year when many couple celebrates their love and affection towards each other
    through spending quality time with the other, having a romantic
    dinner together and exchanging gifts. Remember to store your ring in a
    soft, fabric lined box and get away from directly touching the
    diamond portion with the ring.

  19. Μy brother гecommended I might like this web site.

    He was entirepy right. This submit truly made my day.

    You cann’t imagine just how much time I had spent
    for this information! Thanks!

  20. We meet of mice and men pdf her for spare, uncluttered panels.
    Nor will she come live with his autobiographical second novel,
    but with an engaging showman.

  21. Simply wish to say your article is as surprising. The clarity for your submit is just excellent and that i can think you’re a professional on this subject.

    Well along with your permission let me to snatch your feed
    to keep up to date with imminent post. Thanks a million and please
    continue the gratifying work.

    My page free real estate investing event in orlando

  22. Jannie says:

    Laser Therapy For Acne Scars: Laser Rapid acne treatments, Jannie, That Work Scars Honey Lemon Treatment.

  23. great site says:

    I visit day-to-day a few websites and sites to read articles, however this website offers
    feature based content.

  24. Juliana says:

    The symptoms and signs of vaginal yeast infections, an initial herpes outbreak and other medical conditions influencing the female genital tissues are typically
    comparable.

  25. Very good information. Lucky me I came across your website by chance (stumbleupon).

Leave a Reply