Debugging OOB SharePoint. Unable to post comments on SharePoint blogs (SP2013 June CU)
By Anatoly Mironov
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. 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: [code language=“javascript” title="_layouts/15/clienttemplates.debug.js" firstline=“2698”] 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; } } [/code] This is where the error occurs but doesn’t appear in the script console. Here is the error: [code] 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)” [/code]
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) [code language=“javascript” firstline=“5131” title=“ScriptResource.axd (SP 2013 June CU)” highlight=“5141”] $get = $type.getElementById = function DomElement$getElementById(id, element) { /// Finds an element by id. /// The id of the element to find. /// /// The element, or null if it was not found. 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); } [/code] [code language=“javascript” firstline=“246” title=“ScriptResource.axd (SP 2013 June CU)” highlight=“251”] get: function get(selector, context) { /// Queries the DOM for a single DOM element. /// /// /// Selector for a DOM element based on id (#<id>), class (.<name>), or tag name (<tagname>). //// More complex selectors may be used if jQuery is loaded. /// If multiple elements match the selector, the first one is returned. /// /// An element, array of elements, or Sys.UI.TemplateContext to restrict the query within. /// The matching element, or null if none match. return (context && typeof(context.get) === “function”) ? context.get(selector) : this._find(selector, context, true); }, [/code] [code language=“javascript” title=“ScriptResource.axd (SP 2013 June CU)” highlight=“3”] _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()); } } … }, [/code]
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) [code language=“javascript” firstline=“246” title=“ScriptResource.axd (SP 2013 RTM)” highlight=“4229”] var $get = Sys.UI.DomElement.getElementById = function Sys$UI$DomElement$getElementById(id, element) { /// /// /// /// 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; } [/code] 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:
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: [code language=“javascript” highlight=“1,4” title=“tweaked $get”] $get_asFoundInJuneCU = $get $get = function () { var id = arguments[0]; return /\{/.test(id) ? $get_asFoundInRTM.apply(null, arguments) : $get_asFoundInJuneCU.apply(null, arguments); } [/code] 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.
Comments from Wordrpess.com
SharePoint 2013 Build Numbers and CU’s - Steve Chen [MSFT] Sr. Support Escalation Engineer - Site Home - TechNet Blogs - Nov 2, 2013
[…] Known Issue 1Issue 2 […]
avishnyakov (@avishnyakov) - Dec 3, 2013
Gosh, this is something!
Anatoly Mironov - Dec 3, 2013
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.
SharePoint 2013 Build Numbers and CU’s - Steve Chen [MSFT] Sr. Support Escalation Engineer - Site Home - TechNet Blogs - Feb 3, 2014
[…] Known Issue 1 Known Issue 2 […]
aburdin - Jan 6, 2015
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 - Feb 4, 2015
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.
[…] Known Issue 1 Known Issue 2 […]