Click here to Skip to main content
15,867,686 members
Articles / Productivity Apps and Services / Sharepoint

FIXED: InfoPath 2013 JSON undefined error on IE 11

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
14 Apr 2017CPOL4 min read 11.6K   1   1

Introduction

This article is about the "JSON undefined" error in InfoPath 2013 forms when the PeopePicker is used, and explains how the error can be fixed. The solution is presented first. Secondly, it explains when and why the error occurs, and explains why many solutions do not work on Stackoverflow, Codeproject, or Google Search.

Solution

Douglas Crockford has provided the json2.js script on GitHub. Make a copy of this script and paste it into the LAYOUTS directory in SharePoint 2013. Typically, you create a directory scripts before and paste json2.js into that directory. Locate the file pickerdialog.master in the LAYOUTS directory and make a copy of this file for backup. Open the file pickerdialog.master and find the following line

<sharepoint:scriptlink language="javascript" name="core.js" localizable="false" runat="server" />

Above this line, create this entry

<sharepoint:scriptlink language="javascript" name="/_layouts/15/Scripts/json2.js" localizable="false" runat="server" />

Save the modification in the file pickerdialog.master.

Now you can open an InfoPath 2013 form which contains a PeoplePicker Control in Internet Explorer 11. Make sure that the compatibility mode is disabled in Internet Explorer 11 for the SharePoint 2013 domain. Try to select a user with the PeoplePicker Control. The "JSON undefined" error is no longer displayed.

Why this solution

The advantage of this solution is that it can work with any user without making settings in compatibility mode in Internet Explorer 11. Changing the compatibility mode is stupid because the behavior of the PeoplePicker dialog in an InfoPath form is not changed. In many solutions on Stackoverflow or CodeProject and on many other sites this is explained. This can work for one user. For many users, you need to tell them how to change the compatibility mode. Imagine your company has 1000 users. This solution is not practical.
Another advantage, json2 checks if the native JSON is available in the browser. It only works when it does not find the native JSON.

Another very common solution is to change the META tags X-UA-Compatible in the file pickerdialog.master from

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

to

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

or

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

But that's nonsense, too. The PeoplePicker dialog is loaded in the context of the InfoPath form. The InfoPath form defines the compatibility mode outgoing from the browser's browser version and renderengine.

BrowserMajor VersionRender EngineX-UA-Compatible
IE 11 (Without Compatibility Mode)11Trident/7.0IE11
IE11 (With Compatibility Mode)7Trident/7.0IE8
IE 10 (Without Compatibility Mode)11Trident/7.0IE10
IE 10 (With compatibility mode)7Trident/7.0IE8

There is no way to tell SharePoint to load InfoPath with X-UA-Compatible IE10 or IE11. There is no META tag in the FormServer.aspx file and no server control to set the compatibility mode. If the InfoPath form is loaded in compatibility mode IE8, the JavaScript engine of the IE8 is also loaded. In IE 8 the native JSON was implemented for parsing and serializing. The "JSON undefined" error occurs in the SharePoint Server script resources. The problem is that the native JSON is not present in the IE8 compatibility mode due to a faulty implementation.

Where is X-UA-Compatible IE8 set in InfoPath?

To clarify this question you have to look at the control

InfoPath:XmlFormView

The control can be found in the assembly

Microsoft.Office.InfoPath.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c

The assembly is located in the Global Assembly Cache (GAC).

With the tool ILSpy you can see how the code for writing the META tag X-UA-Compatible is implemented in the assembly.

The Control XmlFormView is located in the Namespace Microsoft.Office.InfoPath.Server.Controls. A private method onDataBindHelper() is implemented in the control. There are two relevant lines in this method

Browser.DetectBrowserAndVersion(HttpContext.Current, sPWeb2.UIVersion, out browser2, out browserVersion);
this.AddIEMetaTag(browserVersion);

The method DetectBrowserAndVersion determines the browser and the major version.

// Microsoft.Office.InfoPath.Server.Util.Browser
        internal static void DetectBrowserAndVersion(HttpContext context, int uiVersion, out Browser browser, out int majorVersion)
        {
            bool flag = uiVersion >= 4;
            BrowserType key;

            if (string.IsNullOrEmpty(context.Request.UserAgent))
            {
                key = BrowserType.None;
                majorVersion = -1;
            }
            else
            {
                majorVersion = context.Request.Browser.MajorVersion;

                if (context.Request.UserAgent.Contains(Browser.BrowserNames[2]))
                {
                    key = BrowserType.Safari;
                }
                else if (string.Compare(context.Request.Browser.Browser, Browser.BrowserNames[1], StringComparison.OrdinalIgnoreCase) == 0 || context.Request.UserAgent.Contains("Trident"))
                {
                    if (flag)
                    {
                        if (context.Request.UserAgent.Contains("Trident/6.0"))
                        {
                            key = BrowserType.IE;
                            majorVersion = 10;
                        }
                        else if (context.Request.UserAgent.Contains("Trident/5.0"))
                        {
                            key = BrowserType.IE;
                            majorVersion = 9;
                        }
                        else if (majorVersion > 7)
                        {
                            key = BrowserType.IE;
                        }
                        else if (majorVersion == 7 && context.Request.UserAgent.Contains("Trident"))
                        {
                            key = BrowserType.IE;
                            majorVersion = 8;
                        }
                        else
                        {
                            key = BrowserType.IE7Strict;
                        }
                    }
                    else
                    {
                        key = BrowserType.IE;
                    }
                }
                else if (string.Compare(context.Request.Browser.Browser, Browser.BrowserNames[3], StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(context.Request.Browser.Browser, "Mozilla", StringComparison.OrdinalIgnoreCase) == 0 || string.Compare(context.Request.Browser.Browser, "FireFox", StringComparison.OrdinalIgnoreCase) == 0 || context.Request.UserAgent.Contains("Mozilla"))
                {
                    key = BrowserType.Netscape;
                }
                else
                {
                    key = BrowserType.None;
                }
            }
            browser = Browser.Browsers[key];
        }

This code works perfectly. The major version and the used browser are read from the request context. The BrowserNames listing is implemented as

// Microsoft.Office.InfoPath.Server.Util.Browser
        private static readonly string[] BrowserNames = new string[]
        {
            "None",
            "IE",
            "Safari",
            "Netscape",
            "Mobile",
            "IE7Strict"
        };

The method AddIEMetaTag adds the META tag X-UA-Compatible to the InfoPath form

// Microsoft.Office.InfoPath.Server.Controls.XmlFormView
        private void AddIEMetaTag(int browserVersion)
        {
            HtmlHead header = this.Page.Header;
            if (header != null && this._controlStage == XmlFormView.ControlStage.BeforeRender)
            {
                SPSite sPSite = SiteAndWebCache.Fetch().EnsureRequestSite();
                StringBuilder stringBuilder = new StringBuilder();
                HtmlMeta htmlMeta = new HtmlMeta();
                htmlMeta.HttpEquiv = "X-UA-Compatible";
                stringBuilder.Append("IE=");
                if (sPSite.CompatibilityLevel < 15)
                {
                    stringBuilder.Append("8");
                }
                else
                {
                    stringBuilder.Append(browserVersion);
                }
                htmlMeta.Content = stringBuilder.ToString();
                header.Controls.AddAt(0, htmlMeta);
            }
        }

You can see that the compatibility mode is set by the browser version if the site's CompatibilityLevel is equal to or greater than 15. If the site's CompatibilityLevel is less than 15, the compatibility mode is set to IE8.

In my opinion there is a problem with this code

The InfoPath form is often loaded with compatibility mode IE8, although Internet Explorer 11 is used. On the basis of the code, you indicate that the browser version is passed to the META Tag X-UA-Compatible correctly. Theoretically! But what if the CompatibilityLevel property of the sPSite object is less than 15? The CompatibilityLevel property gets its value from the major part of the SchemaVersion of the sPSite object. The SPSite object is stored in an InfoPath internal cache. Possibly, when reading from this internal cache, the object loses some information because the required instances are not loaded. And therefore the compatibility mode IE8 could be generated.

Conclusion

The solution provided by me should work for all others. It is not perfect because a SharePoint's own system file is changed by hand. For the next SharePoint update, it may be necessary to replace the pickerdialog.master file with a new version. As long as this does not happen, this solution works.

In a SharePoint farm with 30 site collections and more than 100 InfoPath forms, there are no problems with the PeoplePicker since the implementation of json2.js.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) FMP software & process engineering GmbH
Germany Germany
I am a software developer in southern Germany specializing in the development of solutions all around sharepoint and asp.net.

Comments and Discussions

 
QuestionOliver thanks so Fix is great! Pin
Member 1326173015-Jun-17 7:23
Member 1326173015-Jun-17 7:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.