Могу ли я установить неограниченную длину для maxJsonLength в web.config?

570

Я использую функцию автозаполнения jQuery. Когда я пытаюсь получить список из более чем 17000 записей (каждая из них не будет иметь длину более 10 char), она превышает длину и выдает ошибку:

Информация об исключении:
    Тип исключения: InvalidOperationException
    Сообщение об исключении: ошибка при сериализации или десериализации с использованием JSON JavaScriptSerializer. Длина строки превышает значение, заданное для свойства maxJsonLength.

Можно ли установить неограниченную длину для maxJsonLength в web.config? Если нет, какова максимальная длина, которую я могу установить?

  • 1
    Нечто упомянутое, что может быть довольно очевидным, поэтому, пожалуйста, извините, если вы уже подумали, если это так; Строка Json также содержит фигурные скобки вокруг каждой записи, кавычки вокруг каждого имени поля [и значения], а также имя и значение поля. Поэтому может быть полезно установить имя поля в виде одного символа, а также убедиться, что если значение не является строкой, вы правильно установите тип поля, чтобы он не содержал кавычек.
Теги:
asp.net-mvc

26 ответов

585
Лучший ответ

ПРИМЕЧАНИЕ. этот ответ относится только к веб-сервисам, если вы возвращаете JSON из метода Controller, убедитесь, что вы также прочитали этот ответ SO ниже: https://stackoverflow.com/questions/1151987/can-i-set-an-unlimited-length-for-maxjsonlength-in-web-config


Свойство MaxJsonLength не может быть неограниченным, является целочисленным свойством, которое по умолчанию равно 102400 (100 тыс.).

Вы можете установить свойство MaxJsonLength на свой web.config:

<configuration> 
   <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
</configuration> 
  • 145
    Это целое число, поэтому максимальное значение, которое вы можете установить: 2147483644
  • 54
    @despart: Вы имеете в виду 2 147 483 647.
Показать ещё 14 комментариев
415

Если вы используете MVC 4, обязательно зачитайте этот ответ.


Если вы все еще получаете ошибку:

  • после установки свойства maxJsonLength на максимальное значение в web.config
  • и вы знаете, что длина данных меньше этого значения.
  • и вы не используете метод веб-службы для сериализации JavaScript

Ваша проблема в том, что:

Значение свойства MaxJsonLength применяется только к внутреннему экземпляру JavaScriptSerializer, который используется асинхронным уровнем связи для вызова методов Web-сервисов. (MSDN: ScriptingJsonSerializationSection.MaxJsonLength Свойство)

В принципе, "внутренний" JavaScriptSerializer оценивает значение maxJsonLength при вызове из веб-метода; прямое использование JavaScriptSerializer (или использование с помощью MVC action-method/Controller) делает не значение свойства maxJsonLength, по крайней мере, не из раздела systemWebExtensions.scripting.webServices.jsonSerialization в файле web.config.

В качестве обходного пути вы можете сделать следующее в своем контроллере (или в любом месте):

var serializer = new JavaScriptSerializer();

// For simplicity just use Int32 max value.
// You could always read the value from the config section mentioned above.
serializer.MaxJsonLength = Int32.MaxValue;

var resultData = new { Value = "foo", Text = "var" };
var result = new ContentResult{
    Content = serializer.Serialize(resultData),
    ContentType = "application/json"
};
return result;

Этот ответ - это моя интерпретация этого ответа на форум asp.net.

  • 5
    Ваш ответ был действительно полезен, так как я использую метод результата действия Json() в asp.net mvc.
  • 3
    Да, я был Json () тоже страдают. Спасибо!
Показать ещё 10 комментариев
265

В MVC 4 вы можете:

protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult()
    {
        Data = data,
        ContentType = contentType,
        ContentEncoding = contentEncoding,
        JsonRequestBehavior = behavior,
        MaxJsonLength = Int32.MaxValue
    };
}

в вашем контроллере.

  • 6
    Я могу подтвердить, что все вышеперечисленное работает как шарм в MVC 4, спасибо вам, фаниш.
  • 9
    Я также могу подтвердить. Поместить этот код в базовый контроллер, безусловно, самый чистый предложенный подход.
Показать ещё 16 комментариев
57

Вы можете настроить максимальную длину для запросов json в файле web.config:

<configuration>
    <system.web.extensions>
        <scripting>
            <webServices>
                <jsonSerialization maxJsonLength="....">
                </jsonSerialization>
            </webServices>
        </scripting>
    </system.web.extensions>
</configuration>

Значение по умолчанию для maxJsonLength 102400. Для получения дополнительной информации см. Эту страницу MSDN: http://msdn.microsoft.com/en-us/library/bb763183.aspx

  • 1
    Какое значение хранится в этом целом числе? Это какое-то количество символов? Я думаю, что я спрашиваю, почему целое число используется? Спасибо!
  • 0
    @ eaglei22 число представляет, сколько байтов может быть использовано для maxJsonLength. Как упоминалось в M4N, по умолчанию используется значение 102400 (100 КБ).
Показать ещё 1 комментарий
30

У меня возникла эта проблема в веб-формах ASP.NET. Он полностью игнорировал настройки файла web.config, поэтому я сделал это:

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        serializer.MaxJsonLength = Int32.MaxValue; 

        return serializer.Serialize(response);

Конечно, в целом это ужасная практика. Если вы отправляете много данных в вызове веб-службы, вы должны посмотреть на другой подход.

  • 1
    это сработало для вас? где вы разместили этот код?
  • 0
    Наша проблема заключалась в том, что у нас была текстовая область, которая позволяла использовать HTML, а люди встраивали изображения в виде HTML, что приводило к тому, что запись становилась очень большой, а сериализатор JSON не работал. Я думаю, если это можно сделать, пользователи сделают это ...
Показать ещё 7 комментариев
19

Я исправил его.

//your Json data here
string json_object="........";
JavaScriptSerializer jsJson = new JavaScriptSerializer();
jsJson.MaxJsonLength = 2147483644;
MyClass obj = jsJson.Deserialize<MyClass>(json_object);

Это работает очень хорошо.

  • 0
    Потрясающие! Это единственное решение, которое сработало для меня и в любом случае лучше, так как оно не является глобальным изменением. Спасибо!
15

если после реализации вышеуказанного добавления в ваш web.config вы получите "Unrecognized configuration section system.web.extensions". затем попробуйте добавить это в свой web.config в разделе <ConfigSections>:

            <sectionGroup name="system.web.extensions" type="System.Web.Extensions">
              <sectionGroup name="scripting" type="System.Web.Extensions">
                    <sectionGroup name="webServices" type="System.Web.Extensions">
                          <section name="jsonSerialization" type="System.Web.Extensions"/>
                    </sectionGroup>
              </sectionGroup>
        </sectionGroup>
  • 4
    У меня была эта проблема. Однако этот ответ не работал для меня. Вместо добавления элемента <sectionGroup>, описанного здесь, я просто переместил весь недавно добавленный блок <system.web.extensions> в самый конец моего web.config ... прямо перед </ configuration>. Тогда это сработало.
  • 0
    Это помогло, но в моей ситуации мне нужно было изменить четвертую строку на <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/> , как показано на этой странице: forums.asp.net/t/1446510.aspx/1
Показать ещё 1 комментарий
14

если вы по-прежнему получаете сообщение об ошибке после настройки web.config следующим образом:  

<configuration> 
   <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
</configuration> 

Я решил это, следуя:

   public ActionResult/JsonResult getData()
   {
      var jsonResult = Json(superlargedata, JsonRequestBehavior.AllowGet);
      jsonResult.MaxJsonLength = int.MaxValue;
      return jsonResult;
    }

Надеюсь, это поможет.

  • 0
    Установка maxJsonLength в web.config нецелесообразна, установка jsonResult.MaxJsonLength должна быть достаточной (по крайней мере, для меня (MVC5))
9

Я следил за остальным ответом и добрался до этого решения:

Когда мне нужно было отправить большой json в действие в контроллере, я получил бы знаменитую "Ошибка при десериализации с помощью JSON JavaScriptSerializer. Длина строки превышает значение, установленное в свойстве maxJsonLength.\r\nПараметр name: поставщик входных значений".

То, что я сделал, это создать новый ValueProviderFactory, LargeJsonValueProviderFactory и установить MaxJsonLength = Int32.MaxValue в методе GetDeserializedObject

public sealed class LargeJsonValueProviderFactory : ValueProviderFactory
{
private static void AddToBackingStore(LargeJsonValueProviderFactory.EntryLimitedDictionary backingStore, string prefix, object value)
{
    IDictionary<string, object> dictionary = value as IDictionary<string, object>;
    if (dictionary != null)
    {
        foreach (KeyValuePair<string, object> keyValuePair in (IEnumerable<KeyValuePair<string, object>>) dictionary)
            LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);
    }
    else
    {
        IList list = value as IList;
        if (list != null)
        {
            for (int index = 0; index < list.Count; ++index)
                LargeJsonValueProviderFactory.AddToBackingStore(backingStore, LargeJsonValueProviderFactory.MakeArrayKey(prefix, index), list[index]);
        }
        else
            backingStore.Add(prefix, value);
    }
}

private static object GetDeserializedObject(ControllerContext controllerContext)
{
    if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
        return (object) null;
    string end = new StreamReader(controllerContext.HttpContext.Request.InputStream).ReadToEnd();
    if (string.IsNullOrEmpty(end))
        return (object) null;

    var serializer = new JavaScriptSerializer {MaxJsonLength = Int32.MaxValue};

    return serializer.DeserializeObject(end);
}

/// <summary>Returns a JSON value-provider object for the specified controller context.</summary>
/// <returns>A JSON value-provider object for the specified controller context.</returns>
/// <param name="controllerContext">The controller context.</param>
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
    if (controllerContext == null)
        throw new ArgumentNullException("controllerContext");
    object deserializedObject = LargeJsonValueProviderFactory.GetDeserializedObject(controllerContext);
    if (deserializedObject == null)
        return (IValueProvider) null;
    Dictionary<string, object> dictionary = new Dictionary<string, object>((IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase);
    LargeJsonValueProviderFactory.AddToBackingStore(new LargeJsonValueProviderFactory.EntryLimitedDictionary((IDictionary<string, object>) dictionary), string.Empty, deserializedObject);
    return (IValueProvider) new DictionaryValueProvider<object>((IDictionary<string, object>) dictionary, CultureInfo.CurrentCulture);
}

private static string MakeArrayKey(string prefix, int index)
{
    return prefix + "[" + index.ToString((IFormatProvider) CultureInfo.InvariantCulture) + "]";
}

private static string MakePropertyKey(string prefix, string propertyName)
{
    if (!string.IsNullOrEmpty(prefix))
        return prefix + "." + propertyName;
    return propertyName;
}

private class EntryLimitedDictionary
{
    private static int _maximumDepth = LargeJsonValueProviderFactory.EntryLimitedDictionary.GetMaximumDepth();
    private readonly IDictionary<string, object> _innerDictionary;
    private int _itemCount;

    public EntryLimitedDictionary(IDictionary<string, object> innerDictionary)
    {
        this._innerDictionary = innerDictionary;
    }

    public void Add(string key, object value)
    {
        if (++this._itemCount > LargeJsonValueProviderFactory.EntryLimitedDictionary._maximumDepth)
            throw new InvalidOperationException("JsonValueProviderFactory_RequestTooLarge");
        this._innerDictionary.Add(key, value);
    }

    private static int GetMaximumDepth()
    {
        NameValueCollection appSettings = ConfigurationManager.AppSettings;
        if (appSettings != null)
        {
            string[] values = appSettings.GetValues("aspnet:MaxJsonDeserializerMembers");
            int result;
            if (values != null && values.Length > 0 && int.TryParse(values[0], out result))
                return result;
        }
        return 1000;
    }
}

}

Затем в методе Application_Start из Global.asax.cs замените ValueProviderFactory новым:

protected void Application_Start()
{
    ...

    //Add LargeJsonValueProviderFactory
    ValueProviderFactory jsonFactory = null;
    foreach (var factory in ValueProviderFactories.Factories)
    {
        if (factory.GetType().FullName == "System.Web.Mvc.JsonValueProviderFactory")
        {
            jsonFactory = factory;
            break;
        }
    }

    if (jsonFactory != null)
    {
        ValueProviderFactories.Factories.Remove(jsonFactory);
    }

    var largeJsonValueProviderFactory = new LargeJsonValueProviderFactory();
    ValueProviderFactories.Factories.Add(largeJsonValueProviderFactory);
}
  • 0
    Я сделал все, что мог, только твой ответ спас мой день, это должен был быть принят ответ
  • 0
    С помощью этого кода мы можем переопределить максимальный предел десериализации контроллера jC, равный 4 МБ, но есть ли способ переопределить максимальный предел десериализации контроллера web-api
9

вы можете написать эту строку в Controller

json.MaxJsonLength = 2147483644;

вы также можете записать эту строку в web.config

<configuration>
  <system.web.extensions>
    <scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
        </webServices>
    </scripting>
  </system.web.extensions>

`

Чтобы быть в безопасности, используйте оба параметра.

9

Если вы получаете эту ошибку из MiniProfiler в MVC, вы можете увеличить значение, установив свойство MiniProfiler.Settings.MaxJsonResponseSize на нужное значение. По умолчанию этот инструмент, кажется, игнорирует значение, установленное в config.

MiniProfiler.Settings.MaxJsonResponseSize = 104857600;

Предоставлено mvc-mini-profiler.

5

Просто установите свойство MaxJsonLength в методе действия MVC

JsonResult json= Json(classObject, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
4

Как насчет некоторой магии атрибутов?

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class MaxJsonSizeAttribute : ActionFilterAttribute
{
    // Default: 10 MB worth of one byte chars
    private int maxLength = 10 * 1024 * 1024;

    public int MaxLength
    {
        set
        {
            if (value < 0) throw new ArgumentOutOfRangeException("value", "Value must be at least 0.");

            maxLength = value;
        }
        get { return maxLength; }
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        JsonResult json = filterContext.Result as JsonResult;
        if (json != null)
        {
            if (maxLength == 0)
            {
                json.MaxJsonLength = int.MaxValue;
            }
            else
            {
                json.MaxJsonLength = maxLength;
            }
        }
    }
}

Затем вы можете применить его глобально, используя глобальную конфигурацию фильтра или контроллер/действие.

  • 0
    Очень хорошо, эта работа для меня.
  • 0
    это помогло мне. Спасибо.
Показать ещё 2 комментария
4

Я предлагаю установить его в Int32.MaxValue.

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
4

Вопрос в том, действительно ли вам нужно вернуть 17 тыс. записей? Как вы планируете обрабатывать все данные в браузере? В любом случае пользователи не будут прокручивать 17000 строк.

Лучший подход заключается в том, чтобы извлекать только "самые лучшие" записи и загружать больше по мере необходимости.

  • 1
    Список по умолчанию от JSON даст 17 тыс. Записей. Но функция автозаполнения будет перечислять только те записи, которые соответствуют символам, которые вводит пользователь, поэтому не нужно больше прокручивать список. Так что мне нужно установить неограниченную длину для maxJsonLength, который может сериализовать данные 17k.
  • 6
    Вы можете использовать комбинацию фильтрации на стороне сервера и на стороне клиента. Может быть сложно отфильтровать все данные на стороне клиента, не говоря уже о задержке в сети.
Показать ещё 1 комментарий
3

Просто наткнулся на это. Я получаю более 6000 записей. Просто решил, что я просто сделаю пейджинг. Как и в, я принимаю номер страницы в моей конечной точке MVC JsonResult, которая по умолчанию равна 0, поэтому она не нужна, например:

public JsonResult MyObjects(int pageNumber = 0)

Тогда вместо того, чтобы сказать:

return Json(_repository.MyObjects.ToList(), JsonRequestBehavior.AllowGet);

Я говорю:

return Json(_repository.MyObjects.OrderBy(obj => obj.ID).Skip(1000 * pageNumber).Take(1000).ToList(), JsonRequestBehavior.AllowGet);

Это очень просто. Затем в JavaScript вместо этого:

function myAJAXCallback(items) {
    // Do stuff here
}

Вместо этого я говорю:

var pageNumber = 0;
function myAJAXCallback(items) {
    if(items.length == 1000)
        // Call same endpoint but add this to the end: '?pageNumber=' + ++pageNumber
    }
    // Do stuff here
}

И добавьте свои записи во все, что вы делали с ними, в первую очередь. Или просто подождите, пока все вызовы не закончатся и не соберет результаты вместе.

2

Если вы сталкиваетесь с такой проблемой в представлении, вы можете использовать метод ниже, чтобы решить эту проблему. Здесь Iused Newtonsoft.

@using Newtonsoft.Json
<script type="text/javascript">
    var partData = @Html.Raw(JsonConvert.SerializeObject(ViewBag.Part));
</script>
  • 0
    Означает ли это, что мне не нужно беспокоиться о максимальной длине, если я использую Json.NET? Я не думаю, что есть способ установить максимальную длину в Json.NET, поэтому я надеюсь, что он работает "из коробки".
2

Я решил проблему с добавлением этого кода:

String confString = HttpContext.Current.Request.ApplicationPath.ToString();
Configuration conf = WebConfigurationManager.OpenWebConfiguration(confString);
ScriptingJsonSerializationSection section = (ScriptingJsonSerializationSection)conf.GetSection("system.web.extensions/scripting/webServices/jsonSerialization");
section.MaxJsonLength = 6553600;
conf.Save();
  • 0
    Это похоже на хакерское решение, но интересный подход в любом случае. Я нашел это полезным, спасибо! Для меня в контроллере apsnet mvc 5 мне пришлось удалить «Текущий» из пространства имен. Я внес пару изменений: string confString = HttpContext.Request.ApplicationPath.ToString(); var conf = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(confString); var section = (System.Web.Configuration.ScriptingJsonSerializationSection)conf.GetSection("system.web.extensions/scripting/webServices/jsonSerialization"); section.MaxJsonLength = int.MaxValue; conf.Save();
2

Для тех, у кого проблемы с MVC3 с JSON, которые автоматически десериализуются для привязки модели и слишком велики, вот решение.

  • Скопируйте код класса JsonValueProviderFactory из исходного кода MVC3 в новый класс.
  • Добавьте строку, чтобы изменить максимальную длину JSON до того, как объект будет десериализован.
  • Замените класс JsonValueProviderFactory новым модифицированным классом.

Благодаря http://blog.naver.com/techshare/100145191355 и https://gist.github.com/DalSoft/1588818 для того, чтобы указать мне в правильном направлении, как это сделать. Последняя ссылка на первом сайте содержит полный исходный код для решения.

2

Вы можете установить его в конфиге, как говорили другие, или вы можете установить на отдельный экземпляр сериализатора, например:

var js = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
2

Похоже, что нет "неограниченного" значения. Значение по умолчанию - 2097152 символов, что эквивалентно 4 МБ строковых данных Unicode.

Как уже отмечалось, 17 000 записей трудно использовать в браузере. Если вы представляете сводный вид, может быть намного эффективнее выполнять агрегацию на сервере и передавать только сводку в браузере. Например, рассмотрите файловую систему brower, мы видим только верхнюю часть дерева, а затем отправляем дальнейшие запросы по мере развертывания. Количество записей, возвращаемых в каждом запросе, сравнительно невелико. Представление древовидного представления может хорошо работать для больших наборов результатов.

  • 3
    довольно странно по умолчанию в коде (новый JavaScriptSerializer ()). MaxJsonLength составляет 2097152 байта, но веб-служба ResponseFormatJson - 102400 байтов, если явно не установлено.
0

Нам не нужны изменения на стороне сервера. вы можете исправить это только с помощью файла web.config Это помогло мне. попробуйте это

<appSettings>
 <add key="aspnet:MaxJsonDeserializerMembers" value="2147483647" />
<add key="aspnet:UpdatePanelMaxScriptLength" value="2147483647" />
</appSettings>  

and   

<system.web.extensions>
<scripting>
  <webServices>
    <jsonSerialization maxJsonLength="2147483647"/>
  </webServices>
</scripting>

0

Решение для WebPorms UpdatePanel:

Добавьте параметр в Web.config:

<configuration>
  <appSettings>
    <add key="aspnet:UpdatePanelMaxScriptLength" value="2147483647" />
  </appSettings>
</configuration>

https://support.microsoft.com/en-us/kb/981884

ScriptRegistrationManager класс содержит следующий код:

// Serialize the attributes to JSON and write them out
JavaScriptSerializer serializer = new JavaScriptSerializer();

// Dev10# 877767 - Allow configurable UpdatePanel script block length
// The default is JavaScriptSerializer.DefaultMaxJsonLength
if (AppSettings.UpdatePanelMaxScriptLength > 0) {
    serializer.MaxJsonLength = AppSettings.UpdatePanelMaxScriptLength;
}  

string attrText = serializer.Serialize(attrs);
0

использовать lib\Newtonsoft.Json.dll

public string serializeObj(dynamic json) {        
    return JsonConvert.SerializeObject(json);
}
-1

Вам не нужно делать с web.config Вы можете использовать короткое свойство во время значения улова списка прохода Например объявите модель, например

public class BookModel
    {
        public decimal id { get; set; }  // 1 

        public string BN { get; set; } // 2 Book Name

        public string BC { get; set; } // 3 Bar Code Number

        public string BE { get; set; } // 4 Edition Name

        public string BAL { get; set; } // 5 Academic Level

        public string BCAT { get; set; } // 6 Category
}

здесь я использую короткие пропорции, такие как BC = штрих-код BE = книжное издание и т.д.

  • 0
    Это не поможет, если большая часть данных находится в значениях свойств
-2

если это значение maxJsonLength является int, то насколько велика его int 32bit/64bit/16bit.... Я просто хочу быть уверенным, что максимальное значение, которое я могу установить как my maxJsonLength

<scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
        </webServices>
    </scripting>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню