JsonValueProviderFactory выбрасывает "запрос слишком большой"

Я получаю исключение, что запрос JSON был слишком большим для десериализации.

Это происходит от JsonValueProviderFactory....

В настоящее время приложение MVC имеет настраиваемое связующее устройство, использующее Json.Net, у которого нет проблем десериализации данных json. Однако я предполагаю, что поставщик стоимости JSON по умолчанию отключается? или имеет какой-то странный предел, встроенный в него?

Возможно, это связано с последней версией MVC4, поскольку при использовании предыдущей сборки MVC4 проблем с большими объемами JSON не возникало.

Итак, есть ли способ изменить настройки фактического связующего значения json?

переход на http://haacked.com/archive/2011/06/30/whatrsquos-the-difference-between-a-value-provider-and-model-binder.aspx

У меня создается впечатление, что это какая-то обычная вещь, которая превращает ее в словарь.... Я не могу найти какой-либо исходный код, связанный с ним, или если есть какие-либо настройки, которые я могу изменить?

Или есть альтернативный ValueBinder, который я мог бы использовать?

или любые другие варианты?

Server Error in '/' Application.
The JSON request was too large to be deserialized.
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: The JSON request was too large to be deserialized.

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: The JSON request was too large to be deserialized.]
   System.Web.Mvc.EntryLimitedDictionary.Add(String key, Object value) +464621
   System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +413
   System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +164
   System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +164
   System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +373
   System.Web.Mvc.JsonValueProviderFactory.AddToBackingStore(EntryLimitedDictionary backingStore, String prefix, Object value) +164
   System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) +116
   System.Web.Mvc.<>c__DisplayClassc.<GetValueProvider>b__7(ValueProviderFactory factory) +34

       System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +151
   System.Linq.WhereSelectEnumerableIterator`2.MoveNext() +177

Ответ 1

Если вы используете JSON.NET для сериализации/десериализации, вы можете заменить JsonValueProviderFactory по умолчанию на пользовательский, как показано в этом сообщении в блоге:

public sealed class JsonDotNetValueProviderFactory : ValueProviderFactory
{
   public override IValueProvider GetValueProvider(ControllerContext controllerContext)
   {
        if (controllerContext == null)
            throw new ArgumentNullException("controllerContext");

        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            return null;

        var reader = new StreamReader(controllerContext.HttpContext.Request.InputStream);
        var bodyText = reader.ReadToEnd();

        return String.IsNullOrEmpty(bodyText) ? null : new DictionaryValueProvider<object>(JsonConvert.DeserializeObject<ExpandoObject>(bodyText, new ExpandoObjectConverter()) , CultureInfo.CurrentCulture);
    }
}

и в вашем Application_Start:

ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault());
ValueProviderFactories.Factories.Add(new JsonDotNetValueProviderFactory());

и если вы хотите придерживаться стандартного factory, который использует класс JavaScriptSerializer, вы можете настроить maxJsonLength в вашем web.config:

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

Ответ 2

Для меня maxJsonLength не был превышен. Мне пришлось добавить следующее:

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

После этого он работал.

Ответ 3

Вышеуказанные предложения не сработали для меня, пока я не попробовал это:

// Global.asax.cs    
protected void Application_Start() {
    MiniProfiler.Settings.MaxJsonResponseSize = int.MaxValue;
}