Friday, December 19, 2014

Sharepoint 2010 and IE9 compatibility

Sharepoint 2010 and IE9 compatibility

I have changed the master page to enable IE9 for some additional fluff on my application pages:

<meta http-equiv="X-UA-Compatible" content="IE=9"/>

However when using the PeopleEditor control, if I enter a name and then click the check names button and then do a postback I receive an internal xsd error:

Namespace prefix 'xsd' is not defined.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.      

 Exception Details: System.InvalidOperationException: Namespace prefix 'xsd' is not defined.

Source Error: 
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 
Stack Trace: 

[InvalidOperationException: Namespace prefix 'xsd' is not defined.]
  System.Xml.Serialization.XmlSerializationReader.ToXmlQualifiedName(String value, Boolean decodeName) +1338197
  Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read1_Object(Boolean isNullable, Boolean checkType) +92
  Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read2_DictionaryEntry(Boolean checkType) +651
  Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDictionaryEntryArray.Read3_ArrayOfDictionaryEntry() +645

[InvalidOperationException: There is an error in XML document (1, 43).]
  System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) +1479
  System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader) +166
  Microsoft.SharePoint.WebControls.EntityEditor.ParseSpanData(String spans) +810
  Microsoft.SharePoint.WebControls.EntityEditor.LoadPostData(String postDataKey, NameValueCollection values) +85
  System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad) +945
  System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2071
I've found a solution for this problem. It has to do with the IE9 document standards for the client's browser. If the document mode is set to IE 9 Standards the issue occurs, if you change the document mode to IE 8 Standards the issue no longer occurs. There is a way to force the page to load using IE 8 Standards in your aspx page. Add the following meta tag to your aspx page and the clients browser will load the page in IE 8 Standards document mode:

<meta http-equiv="X-UA-Compatible" content="IE=8"/>

but This is not a solution. Changing document standards to IE8 is equal to working on IE8. Question is still open. Why is it not working on IE9? How can we keep up the compatibility for IE9?

Solution :

I created a javascript file called entityeditor.ie9fix.js, added the javascript code that will follow, and saved it in /layouts/1033.

In my master page I added

<script type="text/javascript" src="/_layouts/1033/entityeditor.ie9fix.js"></script>

to the very BOTTOM of the page. For some reason using the usual tricks to get it to load after the original entityeditor.js from SharePoint did not work.

Inside the custom javascript is an override of a SharePoint function and a helper function:

function ConvertEntityToSpan(ctx, entity)
        matches[ctx]=new Array();
    var key=entity.getAttribute("Key");
    var displayText=entity.getAttribute("DisplayText");
    var isResolved=entity.getAttribute("IsResolved");
    var description=entity.getAttribute("Description");
    var style='ms-entity-unresolved';
    var spandata="<span id='span"+STSHtmlEncode(key)+"' isContentType='true' tabindex='-1' class='"+style+"' ";
    if (browseris.ie8standard)
        spandata+="onmouseover='this.contentEditable=false;' onmouseout='this.contentEditable=true;' contentEditable='true' ";
        spandata+="contentEditable='false' ";
    spandata+="<div style='display:none;' id='divEntityData' ";
    spandata+="key='"+STSHtmlEncode(key)+"' displaytext='"+STSHtmlEncode(displayText)+"' isresolved='"+STSHtmlEncode(isResolved)+"' ";
    var multipleMatches=EntityEditor_SelectSingleNode(entity, "MultipleMatches");
    var extraData=EntityEditor_SelectSingleNode(entity, "ExtraData");
        var data;
        if(!data) data=extraData.innerXml || extraData.innerHTML;
        if(!data && document.implementation && document.implementation.createDocument)
            var serializer=new XMLSerializer();

                    // **** CUSTOM FUNCTION ****
            data = fixDataInIE9(data);
        if(!data) data='';
        spandata+="<div data='"+STSHtmlEncode(data)+"'></div>";
        spandata+="<div data=''></div>";
            spandata+="<span id='content' tabindex='-1' contenteditable='false'  onmousedown='onMouseDownRw(event);' onContextMenu='onContextMenuSpnRw(event,ctx);' >";
            spandata+="<span id='content' tabindex='-1' contenteditable onmousedown='onMouseDownRw(event);' onContextMenu='onContextMenuSpnRw(event,ctx);' >";
        spandata+="<span id='content' tabindex='-1' contenteditable onmousedown='onMouseDownRw(event);' onContextMenu='onContextMenuSpnRw(event,ctx);' >";
    if (browseris.ie8standard)
    if(displayText !='')
    if (browseris.ie8standard)
    return spandata;
// **** CUSTOM FUNCTION ****
function fixDataInIE9(data)
    if(data.indexOf('<ArrayOfDictionaryEntry>') >= 0)
        data = data.replace('<ArrayOfDictionaryEntry>', '<ArrayOfDictionaryEntry xmlns:xsi=\"\" xmlns:xsd=\"\">');
    return data;

After setting that up and publishing the master page I reloaded my site and had no problems saving people from the people picker. Heck of a lot easier than trying to get everyone to use firefox, or some kind of plugin.

PS: I marked my code with // ** CUSTOM FUNCTION ** 

How to export a schema.xml file for a list from a SharePoint site

How to export a schema.xml file for a list from a SharePoint site In sharepoint, we can retrieve the XML schema of any list by using ...