asp.net-mvc - supera - maxjsonlength asp net mvc 5
Excepción MaxJsonLength en ASP.NET MVC durante JavaScriptSerializer (8)
En una de mis acciones de control estoy devolviendo un JsonResult
muy grande para llenar una grilla.
Recibo la siguiente excepción InvalidOperationException
:
Error durante la serialización o deserialización usando JSON JavaScriptSerializer. La longitud de la cadena excede el valor establecido en la propiedad maxJsonLength.
Establecer la propiedad maxJsonLength
en el web.config
a un valor más alto desafortunadamente no muestra ningún efecto.
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="2147483644"/>
</webServices>
</scripting>
</system.web.extensions>
No quiero devolverlo como una cadena como se menciona en this respuesta SO.
En mi investigación me encontré con this publicación de blog donde se recomienda escribir un propio ActionResult
(por ejemplo, LargeJsonResult : JsonResult
) para eludir este comportamiento.
¿Es esta la única solución?
¿Es esto un error en ASP.NET MVC?
¿Me estoy perdiendo de algo?
Cualquier ayuda sería muy apreciada.
Debe leer la sección de configuración manualmente antes de que su código devuelva un objeto JsonResult. Simplemente lea desde web.config en una sola línea:
var jsonResult = Json(resultsForAjaxUI);
jsonResult.MaxJsonLength = (ConfigurationManager.GetSection("system.web.extensions/scripting/webServices/jsonSerialization") as System.Web.Configuration.ScriptingJsonSerializationSection).MaxJsonLength;
return jsonResult;
Asegúrese de haber definido el elemento de configuración en web.config
Desafortunadamente la configuración predeterminada de JsonResult ignora la configuración de web.config . Así que supongo que necesitarás implementar un resultado json personalizado para superar este problema.
No hay necesidad de una clase personalizada. Esto es todo lo que se necesita:
return new JsonResult { Data = Result, MaxJsonLength = Int32.MaxValue };
donde Result
es esa información que desea serializar.
Parece que esto se ha corregido en MVC4.
Puedes hacer esto, lo cual funcionó bien para mí:
public ActionResult SomeControllerAction()
{
var jsonResult = Json(veryLargeCollection, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = int.MaxValue;
return jsonResult;
}
Puedes intentar definir en tu expresión LINQ solo el campo que necesitarás.
Ejemplo. Imagine que tiene un Modelo con Id, Nombre, Teléfono e Imagen (matriz de bytes) y necesita cargar desde json en una lista de selección.
Consulta LINQ:
var listItems = (from u in Users where u.name.Contains(term) select u).ToList();
El problema aquí es " seleccionar u " que obtiene todos los campos. Entonces, si tienes fotos grandes, booomm.
¿Cómo resolver? muy, muy simple.
var listItems = (from u in Users where u.name.Contains(term) select new {u.Id, u.Name}).ToList();
Las mejores prácticas son seleccionar solo el campo que usará.
Recuerda. Este es un consejo simple, pero puede ayudar a muchos desarrolladores de ASP.NET MVC.
Si utiliza Json.NET para generar la cadena json
, no necesita establecer el valor MaxJsonLength
.
return new ContentResult()
{
Content = Newtonsoft.Json.JsonConvert.SerializeObject(data),
ContentType = "application/json",
};
También podría usar ContentResult
como se sugiere aquí en lugar de JsonResult
subclases de JsonResult
.
var serializer = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue, RecursionLimit = 100 };
return new ContentResult()
{
Content = serializer.Serialize(data),
ContentType = "application/json",
};
Resolví el problema siguiendo este link
namespace System.Web.Mvc
{
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);
}
}
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
//Remove and JsonValueProviderFactory and add JsonDotNetValueProviderFactory
ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault());
ValueProviderFactories.Factories.Add(new JsonDotNetValueProviderFactory());
}