JsonValueProviderFactory выдает «слишком большой запрос» - PullRequest
30 голосов
/ 01 марта 2012

Я получаю исключение из-за того, что 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

Ответы [ 3 ]

68 голосов
/ 01 марта 2012

Если вы используете 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());

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

<system.web.extensions>
    <scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483644"/>
        </webServices>
    </scripting>
</system.web.extensions>
64 голосов
/ 14 марта 2012

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

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

После этого все получилось.

3 голосов
/ 13 декабря 2012

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

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