CHUVASH.eu

CHunky Universe of Vigourous Astonishing SHarepoint :)

Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)

I have had a strange bug. The comment text box in a OOB SharePoint 2013 blog doesn’t appear. It only says: “There are no comments for this post.” In this blog post I’ll tell you how I found the bug and I’ll show you how you can temporarily bring the commenting to life.

comments-not-working-001

I have had luck. While it doesn’t work on the Test Environment, it does actually work on my development machine. The comments text box is rendered as an OnPostRender action in the blog comments display template. After debugging the javascript in hours and comparing the two environments, I just could confirm that displaytemplates are the same. There are two main javascript files that are involved:

  • clienttemplates.js
  • sp.ui.blogs.js

So it must some differences elsewhere. The build versions of the environments are

  • Working Environment:  15.0.4420.1017 (SharePoint 2013 RTM)
  • Not-working Environment: 15.0.4517.1005 (SharePoint 2013 June CU)

No errors are thrown, even on the blog where it doesn’t work. It is because of the permissive try-catch in this function that wraps rendering of the comment text box:

function CallFunctionWithErrorHandling(fn, c, erv, execCtx) {
    if (SPClientRenderer.IsDebugMode(c)) {
        return fn();
    }
    try {
        return fn();
    }
    catch (e) {
        if (c.Errors == null)
            c.Errors = [];
        try {
            e.ExecutionContext = execCtx;
            if (Boolean(SPClientRenderer.AddCallStackInfoToErrors) && typeof execCtx == "object" && null != execCtx) {
                execCtx.CallStack = ULSGetCallstack(CallFunctionWithErrorHandling.caller);
            }
        }
        catch (ignoreErr) { }
        c.Errors.push(e);
        return erv;
    }
}

This is where the error occurs but doesn’t appear in the script console. Here is the error:

ExecutionContext: Object
message: "Syntax error, unrecognized expression: #{B808453A-141A-4091-8467-B6915B8B3E99}-{6C3BF638-43F2-4F12-A297-DEF18635540E}-CommentContainer"
stack: "Error: Syntax error, unrecognized expression: #{B808453A-141A-4091-8467-B6915B8B3E99}-{6C3BF638-43F2-4F12-A297-DEF18635540E}-CommentContainer
    at Error ()
    at Function.st.error (jquery-1.9.1.min.js:4:10926)
    at ft (jquery-1.9.1.min.js:4:17138)
    at wt (jquery-1.9.1.min.js:4:19823)
    at Function.st (jquery-1.9.1.min.js:4:6140)
    at b.fn.extend.find (jquery-1.9.1.min.js:4:20941)
    at b.fn.b.init (jquery-1.9.1.min.js:3:1126)
    at b (jquery-1.9.1.min.js:3:206)
    at /ScriptResource.axd:344:53
    at _foreach (ScriptResource.axd:33:17)"

What? jQuery error? Why?

It turns out that jQuery is used to get the html element for the comments area in the server with June CU, but not in the Server with SharePoint 2013 RTM.

To get the reference to the comments area, it invokes the $get method, which invokes Sys.get which in some cases invokes the jQuery (if present)

$get implementation in SP 2013 June CU

These are the functions which can be found in the SharePoint 2013 June CU (15.0.4517.1005)

$get = $type.getElementById = function DomElement$getElementById(id, element) {
    /// <summary locid="M:J#Sys.UI.DomElement.getElementById">Finds an element by id.</summary>
    /// <param name="id" type="String">The id of the element to find.</param>
    /// <param name="element" domElement="true" optional="true" mayBeNull="true"></param>
    /// <returns domElement="true" mayBeNull="true">The element, or null if it was not found.</returns>
    var e = Function._validateParams(arguments, [
        {name: "id", type: String},
        {name: "element", mayBeNull: true, domElement: true, optional: true}
    ]);
    if (e) throw e;
    return Sys.get("#" + id, element || null);
}

 

        get: function get(selector, context) {
            /// <summary>Queries the DOM for a single DOM element.</summary>
            /// <validationOptions enabled="false" />
            /// <param name="selector">
            /// Selector for a DOM element based on id (#&lt;id>), class (.&lt;name>), or tag name (&lt;tagname>).
            //// More complex selectors may be used if jQuery is loaded.
            /// If multiple elements match the selector, the first one is returned.
            /// </param>
            /// <param name="context" optional="true" mayBeNull="true">An element, array of elements, or Sys.UI.TemplateContext to restrict the query within.</param>
            /// <returns>The matching element, or null if none match.</returns>
            return (context && typeof(context.get) === "function") ?
                context.get(selector) :
                this._find(selector, context, true);
        },

 

_find: function _find(selector, context, single, filter) {
    ...
    else if (window.jQuery) {
        if (!filter) {
            found.push.apply(found, jQuery(selector, context).get());
        }
        if (includeSelf) {
            found.push.apply(found, jQuery(context).filter(selector).get());
        }
    }
    ...
},

older (but working) $get implementation in SharePoint 2013 RTM

These are two versions which can be found in the older SharePoint Release: RTM (15.0.4420.1017)

var $get = Sys.UI.DomElement.getElementById = function Sys$UI$DomElement$getElementById(id, element) {
    /// <summary locid="M:J#Sys.UI.DomElement.getElementById" />
    /// <param name="id" type="String"></param>
    /// <param name="element" domElement="true" optional="true" mayBeNull="true"></param>
    /// <returns domElement="true" mayBeNull="true"></returns>
    var e = Function._validateParams(arguments, [
        {name: "id", type: String},
        {name: "element", mayBeNull: true, domElement: true, optional: true}
    ]);
    if (e) throw e;
    if (!element) return document.getElementById(id);
    if (element.getElementById) return element.getElementById(id);
    var nodeQueue = [];
    var childNodes = element.childNodes;
    for (var i = 0; i < childNodes.length; i++) {
        var node = childNodes[i];
        if (node.nodeType == 1) {
            nodeQueue[nodeQueue.length] = node;
        }
    }
    while (nodeQueue.length) {
        node = nodeQueue.shift();
        if (node.id == id) {
            return node;
        }
        childNodes = node.childNodes;
        for (i = 0; i < childNodes.length; i++) {
            node = childNodes[i];
            if (node.nodeType == 1) {
                nodeQueue[nodeQueue.length] = node;
            }
        }
    }
    return null;
}

It doesn’t even go to Sys.get and doesn’t even try to use jQuery.

The id of the comment are is a combination of two guids and -CommentContainer. jQuery fails to select an element with this id:
This error happens when you try to select this html element with jQuery in the web console:

comments-not-working-002

Temporary solution

The solution is to prevent using jQuery for this element selection. Hopefully new updates of SharePoint will address this issue. Until then we have to tweak the $get method. To do it very carefully, we can copy the old $get function and call it $get_asFoundInRTM and copy the new $get and call it $get_asFoundInJuneCU

The $get function has to rewritten like that:

$get_asFoundInJuneCU = $get

$get = function () {
    var id = arguments[0];
    return /\{/.test(id)
        ? $get_asFoundInRTM.apply(null, arguments)
        : $get_asFoundInJuneCU.apply(null, arguments);
}

This javascript code has to be loaded after two ScriptResource.axd files. Please be very careful if you have to implement this temporary fix. Probably it is better to wait for an official Microsoft bug fix.

 

UPDATE 2014-03-27

I have discovered that in SP1 it is already solved.

Advertisements

7 responses to “Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)

  1. Pingback: SharePoint 2013 Build Numbers and CU's - Steve Chen [MSFT] Sr. Support Escalation Engineer - Site Home - TechNet Blogs

    • Anatoly Mironov 2013-12-11 at 22:28

      Yes, it took some time to find. First, we thought it was a bug caused by our code. But it wasn’t so. In Vanilla SharePoint 2013 June CU the problem doesn’t occur unless you’ve added a jQuery reference.

  2. Pingback: SharePoint 2013 Build Numbers and CU's - Steve Chen [MSFT] Sr. Support Escalation Engineer - Site Home - TechNet Blogs

  3. Pingback: Stato degli aggiornamenti di SharePoint 2013 - ISG - Italian SharePoint Group - Site Home - MSDN Blogs

  4. aburdin 2015-01-31 at 04:29

    Faced the exact same problem with blog’s comments with SP2013 December 2014 CU (15.0.4675.1000) and was frustrated and curious about how MS could release same bug second time after more than year.
    So I started to dig a little bit deeper and found interesting thing: on working environment (same BuildVersion) ScriptResource.axd was generated by System.Web.Extensions assembly, but on non-working – by AjaxControlToolkit.
    I think that in your case AjaxControlToolkit also was the source of the problem, not June CU (also because of the fact you mention in comment that Vanilla SP2013 June CU doesn’t have such problem).
    So, for those who may face the same problem – check if AjaxControlToolkit somewhere in web.config. 🙂
    After removing AjaxControlToolkit from WebApplication’s web.config comment textbox shown again.

    I’m really curious about how handler determine which assembly will be used to generate MicrosoftAjax.js. If someone knows it, please be kind to share. Thanks.

    • Anatoly Mironov 2015-02-26 at 12:28

      In my case, the problem was gone when we installed October 2013 CU. I know, bad things can happen if you have AjaxControlToolkit. That tool is old and is based on archaic ideas. So I recommend to avoid it in SharePoint 2010 and SharePoint 2013. No surprise that it affected SharePoint OOB comment fields. Thanks for your sharing, aburdin.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Вула Чăвашла

VulaCV - Чăвашла вулаттаракан сайт

Discovering SharePoint

And going crazy doing it

Bram de Jager talking Office 365, SharePoint and Azure

My view and thoughts on Productivity and more.

My programming life

and everything in between

SharePoint Development Lab by @avishnyakov

It is a good place to share some SharePoint stories and development practices.

SharePoint Dragons

Nikander & Margriet on SharePoint

Paul J. Swider - RealActivity

RealActivity is a specialized healthcare services and solution advisory firm.

Mai Omar Desouki - Avid SharePointer

Egyptian & Vodafoner - Senior SharePoint Consultant

Cameron Dwyer | Office 365, SharePoint, Outlook, OnePlace Solutions

Office 365, SharePoint, OnePlace Solutions & Life's Other Little Wonders

paul.tavares

Me and My doings!

Share SharePoint Points!!

By Mohit Vashishtha

Jimmy Janlén "Den Scrummande Konsulten"

Erfarenheter, synpunkter och raljerande om Scrum från Jimmy Janlén

SPJoel

SharePoint for everyone

SharePointRyan

Ryan Dennis is a SharePoint Solution Architect with a passion for SharePoint and PowerShell

SharePoint 2020

The Vision for a Future of Clarity

Aharoni in Unicode, ya mama

Treacle tarts for great justice

... And All That JS

JavaScript, Web Apps and SharePoint

%d bloggers like this: