0

We're using Sitecore 8.1 Update 2 and have an issue where there is an instance where we have are a few hundred items under a single Parent item in our site. These child items show fine in the Content Editor Treeview, if a little slow to load them. I know best practice is to limit this to 100-200 items, it is however usable without converting the parent item to a Bucket. Re-architecting the structure at this stage isn't really an option.

However when using the Link Browser it shows the parent item but won't let me browse the child items. I get this error:

ERROR: No data from server

Update - here is a screenshot showing the parent item high-lighted with a red circle and the children failing to load.

enter image description here

Is there a hard limit on the number of items that the Link Browser support?

Eventually I want to convert these to a bucket but I'm looking for an interim solution in the short term.

  • Do you get the error only for this particular tree or all (i.e. ones with only a few items under the parent)? – jammykam Jan 9 '17 at 14:37
  • @jammykam yeah I can browse and select other parent items with 300-500 children but not this one. I think this has a thousand or more items though from looking again at how many there are. It seems odd that the Tree view is working fine but not the Insert Internal Link Modal. – Adam Seabridge Jan 9 '17 at 14:46
  • @aseabridge is it generic link field and when you try to open insert link option on the modal dialog where it is being opened you are getting this error? – Mrunal Daftari Jan 10 '17 at 16:58
  • @MrunalDaftari yes it's a general link field and is happening on all templates when I click to browse for a link and select this parent item with lots of children. I've added an screenshot to my question showing you when this is happening. It's when I click the arrow next to the item hight-lighted with a red circle. It looks to be an issue with the Sitecore js file when it's trying to get the child items. – Adam Seabridge Jan 10 '17 at 18:00
  • 1
    @aseabridge can you try increasing below value in sitecore.config file and see what happens? you can read description and then make proper call. <setting name="LinkDatabase.MaximumBatchSize" value="1000" /> – Mrunal Daftari Jan 10 '17 at 19:09
5

I figured this out.

I made the update to change the value of LinkDatabase.MaximumBatchSize to 1000 as suggested and it didn't work.

<sitecore>
    <settings>
        <setting name="LinkDatabase.MaximumBatchSize">
            <patch:attribute name="value">1000</patch:attribute>
        </setting>
    </settings>
</sitecore>

I then looked at the console in more detail in Chrome and saw this error:

"Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property."

After some Googling I found I can update this via the web.config like so:

<system.web.extensions xdt:Transform="Insert">
        <scripting>
            <webServices>
                <jsonSerialization maxJsonLength="2147483647"/>
            </webServices>
        </scripting>
</system.web.extensions>

Again this didn't work :-(. I think the Json Serialization code ignores this setting.

Then I came across this Blog Post by Dirk Schäfauer: https://seitenkern.com/2014/03/28/sitecore-7-mvc-json-serialization-and-maxjsonlength/

This post says I need A custom JsonSerializer, a PreprocessRequest Pipeline and .config to patch in my pipeline. This code is outdated for 8.1 though so I've updated it below:

JsonSerializer:

namespace SitecoreContrib.Serialization
 {
      public class LargeJsonSerializer : ISerializer
    {
        public string SerializedDataMediaType
        {
            get { return "application/json"; }
        }

        public string Serialize(object value)
        {
            Assert.ArgumentNotNull(value, "value");
            var scriptSerializer = new JavaScriptSerializer { MaxJsonLength = 2097152 };
            var setting = Settings.GetSetting("JsonSerialization.MaxLength");
            int result;
            if (!string.IsNullOrEmpty(setting) && !scriptSerializer.MaxJsonLength.ToString(CultureInfo.InvariantCulture).Equals(setting, StringComparison.InvariantCultureIgnoreCase) && int.TryParse(setting, out result))
            {
                scriptSerializer.MaxJsonLength = result;
            }
            return scriptSerializer.Serialize(value);
        }
    }
  }

Pipeline:

namespace SitecoreContrib.Serialization.Pipelines.PreprocessRequest
{
      public class RewriteUrlForLargeJsonResponse : RewriteUrl
    {
        public override void Process(PreprocessRequestArgs arguments)
        {
            Assert.ArgumentNotNull((object)arguments, "arguments");
            try
            {
                string localPath = arguments.Context.Request.Url.LocalPath;
                if (!localPath.StartsWith("/-/item/"))
                    return;
                Sc.ItemWebApi.Context.Current = new Sc.ItemWebApi.Context
                {
                    Serializer = (ISerializer)new LargeJsonSerializer(),
                    Version = GetVersion(localPath),
                    ResponseOutputBuilder = new ResponseOutputBuilder()
                };
                Rewrite(arguments.Context);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }

        private static int GetVersion(string path)
        {
            Assert.ArgumentNotNull((object)path, "path");
            string str = path.TrimStart('/').Split('/')[2];
            Assert.IsTrue(str.StartsWith("v"), "Version token is wrong.");
            int result;
            Assert.IsTrue(int.TryParse(str.Replace("v", string.Empty), out result), "Version not recognized.");
            return result;
        }

        private static void Rewrite(HttpContext context)
        {
            Assert.ArgumentNotNull((object)context, "context");
            Uri url = context.Request.Url;
            string[] strArray1 = url.LocalPath.TrimStart('/').Split('/');
            int length = strArray1.Length - 3;
            string[] strArray2 = new string[length];
            Array.Copy((Array)strArray1, 3, (Array)strArray2, 0, length);
            string str1 = string.Format("/{0}", (object)string.Join("/", strArray2));
            string str2 = url.Query.TrimStart('?');
            WebUtil.RewriteUrl(new UrlString
            {
                Path = str1,
                Query = str2
            }.ToString());
        }
    }
 }

Config:

<sitecore>
    <pipelines>
      <preprocessRequest>
        <processor type="SitecoreContrib.Serialization.Pipelines.PreprocessRequest.RewriteUrlForLargeJsonResponse, SitecoreContrib.Serialization" patch:instead="*[@type='Sitecore.ItemWebApi.Pipelines.PreprocessRequest.RewriteUrl, Sitecore.ItemWebApi']" />
      </preprocessRequest>
    </pipelines>
    <settings>
      <!-- JsonSerialization.MaxLength
           Specifies the maximum length of JSON strings which can be serialized by the JsonSerializer.
           Value is specified in bytes. Default value: 2097152 (2 MB)
      -->
      <setting name="JsonSerialization.MaxLength" value="2147483647" />
    </settings>
  </sitecore>

Thats it, this should work well and load large json datasets for you when you have lots of sub-items.

  • Thanks for posting this fix, worked perfectly for me on my 8.2 instance – Ryan Durkin May 4 '18 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.