Czy mogę ustawić nieograniczoną długość dla maxJsonLength w web.config?

663

Korzystam z funkcji autouzupełniania jQuery. Kiedy próbuję pobrać listę ponad 17000 rekordów (każda nie będzie miała więcej niż 10 znaków), przekracza ona długość i zgłasza błąd:

Informacje o wyjątku:
Typ wyjątku: InvalidOperationException
Komunikat o wyjątku: Błąd podczas serializacji lub deserializacji przy użyciu JSON JavaScriptSerializer. Długość łańcucha przekracza wartość ustawioną we właściwości maxJsonLength.

Czy mogę ustawić nieograniczoną długość dla maxJsonLengthw web.config? Jeśli nie, jaka jest maksymalna długość, którą mogę ustawić?

Prasad
źródło
1
Coś wspomnieć, co może być dość oczywiste, więc przepraszam, jeśli już pomyślałeś; ciąg Json zawiera także nawiasy klamrowe wokół każdego rekordu, cudzysłowy wokół nazwy każdego pola [i wartości], a także nazwę i wartość pola. Przydatne może być więc ustawienie nazwy pola jako pojedynczego znaku, a także upewnienie się, że jeśli wartość nie jest łańcuchem, to należy poprawnie ustawić typ pola, aby nie zawierał cudzysłowów.
MichaelJTaylor

Odpowiedzi:

719

UWAGA: ta odpowiedź dotyczy tylko usług sieciowych, jeśli zwracasz JSON z metody kontrolera, pamiętaj również o przeczytaniu poniższej SO: https://stackoverflow.com/a/7207539/1246870


Właściwość MaxJsonLength nie może być nieograniczona, jest to liczba całkowita, której domyślna wartość to 102400 (100k).

Możesz ustawić MaxJsonLengthwłaściwość na swoim web.config:

<configuration> 
   <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
</configuration> 
CMS
źródło
153
Jest to liczba całkowita, więc maksymalna wartość, którą można ustawić to: 2147483644
David Espart
57
@despart: Masz na myśli 2 147 483 647.
Dercsár
6
@ kmcc049, IMO wartości nie są nieprawidłowe, ponieważ jeśli spojrzysz na pytanie, OP nie pyta „jaka jest domyślna wartość maxJsonLength?” (BTW, drugą najczęściej głosowaną odpowiedzią jest odpowiedź na to złe pytanie), próbuje ustawić tę właściwość na „nieograniczoną”, ale ponieważ jest liczbą całkowitą, maksymalna możliwa wartość jest 2147483647taka, jak wskazują @depsart i @ Descár.
CMS
11
Świetnie, ale zwróć uwagę na odpowiedź Davida Murdocha poniżej, jeśli masz ten problem podczas korzystania z MVC return Json()lub czegoś takiego
BritishDeveloper
3
@ Dercsár: o co chodzi? 2147483644 jest największą liczbą całkowitą doskonale podzielną przez 1024.
naveen
461

Jeśli używasz MVC 4 , koniecznie sprawdź również tę odpowiedź .


Jeśli nadal pojawia się błąd:

  • po ustawieniu maxJsonLengthmaksymalnej wartości właściwości w pliku web.config
  • i wiesz, że długość twoich danych jest mniejsza niż ta wartość
  • i nie używasz metody usługi sieciowej do serializacji JavaScript

Twój problem prawdopodobnie:

Wartość właściwości MaxJsonLength dotyczy tylko wewnętrznej instancji JavaScriptSerializer używanej przez asynchroniczną warstwę komunikacyjną do wywoływania metod usług WWW. ( MSDN: Właściwość ScriptingJsonSerializationSection.MaxJsonLength )

Zasadniczo „wewnętrzny” JavaScriptSerializerszanuje wartość maxJsonLengthwywołania z metody internetowej; bezpośrednie użycie JavaScriptSerializer(lub użycie za pomocą metody akcji / kontrolera MVC) nie szanuje maxJsonLengthwłaściwości, przynajmniej nie z systemWebExtensions.scripting.webServices.jsonSerializationsekcji web.config.

Aby obejść ten problem, w kontrolerze (lub w dowolnym innym miejscu) możesz wykonać następujące czynności:

var serializer = new JavaScriptSerializer();

// For simplicity just use Int32's 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;

Ta odpowiedź jest moją interpretacją odpowiedzi na forum asp.net .

David Murdoch
źródło
5
Twoja odpowiedź była bardzo pomocna, ponieważ korzystam z Json()metody wynik działania w asp.net mvc.
jessegavin
3
Tak, ja też cierpiałem na Jsona (). Dzięki!
BritishDeveloper
3
Chociaż jest to całkowicie poprawne i zasługuje na swoje miejsce, jest to jedno z tych pytań, w których warto przeczytać po pierwszej odpowiedzi :). Dzięki!
Nigel
3
Jeśli używasz MVC4, zobacz również odpowiedź @fanisch.
Beyers,
4
Co powiesz na deserializację? Napotkałem ten błąd podczas wiązania modelu akcji.
guogangj
345

W MVC 4 możesz:

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
    };
}

w twoim kontrolerze.

Dodanie:

Dla każdego, kto jest zaskoczony parametrami, które musisz określić, połączenie może wyglądać następująco:

Json(
    new {
        field1 = true,
        field2 = "value"
        },
    "application/json",
    Encoding.UTF8,
    JsonRequestBehavior.AllowGet
);
fanisch
źródło
6
Mogę potwierdzić, że powyższe działa jak urok w MVC 4, dziękuję fanisch.
Beyers,
9
Mogę również potwierdzić. Umieszczenie tego kodu w kontrolerze podstawowym jest zdecydowanie najczystszym proponowanym podejściem.
parlament
15
Działa to również poprzez dodanie „MaxJsonLength = Int32.MaxValue” do wyniku pojedynczej akcji. W przypadku, gdy zmiana nie jest pożądana dla kontrolera lub całego projektu.
Hypnovirus
3
To najlepsza odpowiedź. MaxJsonLength można skonfigurować dla każdego kontrolera.
liang
3
OSTRZEŻENIE: to rozwiązanie wyłącza kompresję (na żądanie) odpowiedzi. Dodaj ten filtr do swojej akcji: stackoverflow.com/questions/3802107/…
Gorgi Rankovski
60

Możesz skonfigurować maksymalną długość żądań json w pliku web.config:

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

Domyślna wartość parametru maxJsonLength to 102400 . Aby uzyskać więcej informacji, zobacz tę stronę MSDN: http://msdn.microsoft.com/en-us/library/bb763183.aspx

M4N
źródło
1
Jaka jest wartość przechowywana w tej liczbie całkowitej? Czy to jakaś liczba znaków? Myślę, że pytam, dlaczego używana jest liczba całkowita? Dzięki!
eaglei22
@ eaglei22 liczba reprezentuje, ile bajtów można użyć dla parametru maxJsonLength. Jak wspomniano M4N, 102400 jest wartością domyślną (100 KB).
Jacob Plonke
to nie działa dla mnie i nie korzystałem z usług internetowych.
kalai
42

jeśli po ustawieniu pliku web.config nadal pojawia się błąd, taki jak:

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

Rozwiązałem to, wykonując następujące czynności:

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

Mam nadzieję, że to powinno pomóc.

Ravi Anand
źródło
2
Ustawienie maxJsonLength w pliku web.config jest niepotrzebne, ustawienie jsonResult.MaxJsonLength powinno wystarczyć (przynajmniej mi się udało (MVC5))
hormberg
To dobrze, ponieważ nie jest to zmiana globalna.
rob_james
40

Miałem ten problem w formularzach sieci Web ASP.NET. Całkowicie ignorowałem ustawienia pliku web.config, więc zrobiłem to:

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        serializer.MaxJsonLength = Int32.MaxValue; 

        return serializer.Serialize(response);

Oczywiście ogólnie jest to okropna praktyka. Jeśli wysyłasz tyle danych w ramach połączenia z serwisem internetowym, powinieneś spojrzeć na inne podejście.

Pchła
źródło
1
czy to zadziałało dla ciebie? gdzie umieściłeś ten kod?
user1012598,
Nasz problem polegał na tym, że mieliśmy obszar tekstowy, który pozwalał na HTML, a ludzie osadzali obrazy jako HTML, co spowodowało, że wpis stał się bardzo duży i szeregowanie JSON nie powiodło się. Myślę, że jeśli da się to zrobić, użytkownicy to zrobią ...
Marko
Proszę opisać, gdzie powinniśmy umieścić ten kod ... @Flea
Koray Durudogan
@KorayDurudogan - umieściłem to w metodzie Ajax, która zwracała odpowiedź, więc w moim kontrolerze. Mam nadzieję, że to pomaga!
Flea
Nie kwestionuję twojej odpowiedzi, ale staram się lepiej zrozumieć, jakie są lepsze podejścia. Mam zapytanie, które w zależności od kryteriów użytkownika określi rozmiar wyniku. Zwracam JsonResult. Czy miałoby to znaczenie, jeśli zwróciłem plik programu Excel?
eaglei22,
22

Naprawiłem to.

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

Pracuje bardzo dobrze.

Mario Arrieta
źródło
Niesamowite! To jedyne rozwiązanie, które zadziałało dla mnie i jest lepsze, ponieważ nie jest to zmiana globalna. Dzięki!
Sealer_05,
20

Postępowałem zgodnie z odpowiedzią szczątkowego i znalazłem rozwiązanie:

Gdy potrzebowałem wysłać dużego jsona do akcji w kontrolerze, otrzymałem słynny „Błąd podczas deserializacji za pomocą JSON JavaScriptSerializer. Długość łańcucha przekracza wartość ustawioną we właściwości maxJsonLength. \ R \ n Nazwa parametru: input dostawca wartości ”.

Utworzyłem nową ValueProviderFactory, LargeJsonValueProviderFactory i ustawiłem MaxJsonLength = Int32.MaxValue w metodzie 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;
     }
  }
}

Następnie w metodzie Application_Start z Global.asax.cs zamień ValueProviderFactory na nową:

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);
}
MSZ
źródło
1
Zrobiłem wszystko, co mogłem, tylko twoja odpowiedź uratowała mi dzień, to powinna była zostać zaakceptowana odpowiedź
Muhammad Waqas Aziz
Za pomocą tego kodu jesteśmy w stanie przesłonić maksymalny limit dezinstalacji kontrolera MVC wynoszący 4 MB, ale istnieje sposób na zastąpienie maksymalnego ograniczenia dezinstalacji kontrolera interfejsu API
Muhammad Waqas Aziz 6'18
17

jeśli po zaimplementowaniu powyższego dodatku w pliku web.config pojawi się „Nierozpoznana sekcja konfiguracji system.web.extensions”. błąd, a następnie spróbuj dodać to do pliku web.config w <ConfigSections>sekcji:

            <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>
bkdraper
źródło
4
Miałem ten problem. Jednak ta odpowiedź nie działała dla mnie. Zamiast dodania elementu <sectionGroup> opisanego tutaj, właśnie przeniosłem cały nowo dodany blok <system.web.extensions> na sam koniec mojego pliku web.config ... tuż przed </configuration>. Potem zadziałało.
ClearCloud8
Pomogło mi to, ale w mojej sytuacji musiałem zmienić czwartą linię na <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>, jak widać na tej stronie: forums.asp.net/t/1446510.aspx/1
Nathan
@ ClearCloud8 Natychmiast rozpowszechnij ten komentarz na tej stronie.
Jack Nutkins
11

możesz napisać ten wiersz w kontrolerze

json.MaxJsonLength = 2147483644;

możesz również napisać ten wiersz w web.config

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

`

Aby być bezpiecznym, użyj obu.

Pankaj Sapkal
źródło
10

Jeśli otrzymujesz ten błąd z MiniProfiler w MVC, możesz zwiększyć wartość, ustawiając właściwość MiniProfiler.Settings.MaxJsonResponseSizena pożądaną wartość. Domyślnie to narzędzie wydaje się ignorować wartość ustawioną w config.

MiniProfiler.Settings.MaxJsonResponseSize = 104857600;

Dzięki uprzejmości mini-profilera mvc .

wolfyuk
źródło
10

Wystarczy ustawić właściwość MaxJsonLength w metodzie Action MVC

JsonResult json= Json(classObject, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
Aftab Ahmed Kalhoro
źródło
9

Sugeruję ustawienie go na Int32.MaxValue.

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
Santhosh
źródło
9

Co powiesz na magię atrybutów?

[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;
            }
        }
    }
}

Następnie możesz zastosować go globalnie, używając globalnej konfiguracji filtra lub kontrolera / akcji.

Balázs
źródło
Świetna odpowiedź. Ładne użycie niestandardowych atrybutów. Zastanawiasz się, czy istnieje konkretny (techniczny) powód, dla którego ustawiłeś domyślną wartość 10 MB jednego bajtu znaków zamiast Max (int. MaxValue)?
Josh
@Josh Nie, nie było tego specjalnego powodu.
Balázs
5

Pytanie naprawdę brzmi, czy naprawdę musisz zwrócić 17k rekordów? Jak zamierzasz obsługiwać wszystkie dane w przeglądarce? Użytkownicy i tak nie będą przewijać 17000 wierszy.

Lepszym podejściem jest pobranie tylko „kilku pierwszych” rekordów i załadowanie większej liczby zgodnie z wymaganiami.

Chetan Sastry
źródło
1
Domyślna lista z json da 17k rekordów. Ale funkcja autouzupełniania wyświetli tylko te rekordy, które pasują do znaków wpisywanych przez użytkownika, więc nie trzeba więcej przewijać listy. SO potrzebuję więc ustawić nieograniczoną długość dla maxJsonLength, która może serializować dane 17k.
Prasad
6
Możesz użyć kombinacji filtrowania po stronie serwera i klienta. Filtrowanie wszystkich danych po stronie klienta może być trudne, nie mówiąc już o opóźnieniu w sieci.
Chetan Sastry
1
Po tym, jak jakiś czas temu dotarłem do tego samego problemu, zdecydowałem się zaimplementować moduł obsługi „onsearch” dla autouzupełniania i poprosić serwis internetowy o przekazanie tekstu „wyszukiwania” i wykonanie zapytania Top10 przy użyciu kryteriów wyszukiwania jako filtra. Oznaczało to więcej indywidualnych żądań ajax, które po prostu otrzymywały pełną listę przy ładowaniu strony, ale także oznaczało, że wszystkie żądania / odpowiedzi były znacznie mniejsze.
Mike U
3

Możesz ustawić go w konfiguracji, jak powiedzieli inni, lub możesz ustawić indywidualne wystąpienie serializatora, takie jak:

var js = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
Caleb Postlethwait
źródło
3

Dla tych, którzy mają problemy z MVC3 z JSON, który jest automatycznie usuwany z postaci szeregowej dla segregatora modeli i jest zbyt duży, oto rozwiązanie.

  1. Skopiuj kod klasy JsonValueProviderFactory z kodu źródłowego MVC3 do nowej klasy.
  2. Dodaj wiersz, aby zmienić maksymalną długość JSON przed zdekrializowaniem obiektu.
  3. Zastąp klasę JsonValueProviderFactory nową, zmodyfikowaną klasą.

Dzięki http://blog.naver.com/techshare/100145191355 i https://gist.github.com/DalSoft/1588818 za wskazanie mi właściwego kierunku, jak to zrobić. Ostatni link na pierwszej stronie zawiera pełny kod źródłowy rozwiązania.

szczątkowy
źródło
3

Jeśli napotykasz tego rodzaju problem w widoku, możesz go rozwiązać, korzystając z poniższej metody. Tutaj użyłem pakietu Newtonsoft .

@using Newtonsoft.Json
<script type="text/javascript">
    var partData = @Html.Raw(JsonConvert.SerializeObject(ViewBag.Part));
</script>
dush88c
źródło
Czy to oznacza, że ​​nie muszę się martwić o maksymalną długość, jeśli korzystam z Json.NET? Nie sądzę, że istnieje sposób, aby ustawić maksymalną długość w Json.NET, więc mam nadzieję, że po prostu działa po wyjęciu z pudełka.
kimbaudi
1
Doskonała odpowiedź, dziękuję! Działało to również, gdy próbowałem załadować obiekt.
user1299379
3
 JsonResult result = Json(r);
 result.MaxJsonLength = Int32.MaxValue;
 result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
 return result;
Aikansh Mann
źródło
2

Wygląda na to, że nie ma wartości „nieograniczonej”. Domyślnie jest to 2097152 znaków, co odpowiada 4 MB ciągów znaków Unicode.

Jak już zaobserwowano, 17 000 rekordów jest trudnych w użyciu w przeglądarce. Jeśli prezentujesz widok zagregowany, może być znacznie bardziej wydajne wykonanie agregacji na serwerze i przesłanie tylko podsumowania w przeglądarce. Na przykład, rozważmy przeglądarkę systemu plików, widzimy tylko górę drzewa, a następnie wysyłamy kolejne żądania podczas drążenia w dół. Liczba rekordów zwracanych w każdym żądaniu jest stosunkowo niewielka. Prezentacja widoku drzewa może dobrze działać w przypadku dużych zestawów wyników.

djna
źródło
3
raczej dziwnie domyślny w kodzie (nowy JavaScriptSerializer ()). MaxJsonLength ma 2097152 bajtów, ale usługa internetowa ResponseFormatJson ma 102400 bajtów, chyba że jawnie ustawione.
okraść
2

Właśnie na to wpadłem. Dostaję ponad 6000 rekordów. Właśnie zdecydowałem, że zrobię trochę stronicowania. W chwili obecnej akceptuję numer strony w moim punkcie końcowym MVC JsonResult, który jest domyślnie ustawiony na 0, więc nie jest to konieczne, na przykład:

public JsonResult MyObjects(int pageNumber = 0)

Następnie zamiast mówić:

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

Mówię:

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

To jest bardzo proste. Następnie w JavaScript zamiast tego:

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

Zamiast tego mówię:

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

I w pierwszej kolejności dołączaj swoje nagrania do wszystkiego, co z nimi robiłeś. Lub po prostu poczekaj, aż wszystkie połączenia zakończą się i połącz wyniki razem.

vbullinger
źródło
2

Rozwiązałem problem dodając ten kod:

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();
jfabrizio
źródło
Wydaje się, że jest to hackerskie rozwiązanie, ale mimo wszystko interesujące podejście. Przydało mi się to dzięki! Dla mnie w apsnet mvc 5 musiałem usunąć „Current” z przestrzeni nazw. 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();
Dokonałem
2

Alternatywna poprawka ASP.NET MVC 5:

(Mój jest podobny do powyższej odpowiedzi MFC z kilkoma małymi zmianami)

Nie byłem jeszcze gotowy na przejście na Json.NET i w moim przypadku błąd występował podczas żądania. Najlepszym podejściem w moim scenariuszu było zmodyfikowanie tego, JsonValueProviderFactoryktóry stosuje poprawkę do projektu globalnego i można tego dokonać, edytując global.csplik jako taki.

JsonValueProviderConfig.Config(ValueProviderFactories.Factories);

dodaj wpis web.config:

<add key="aspnet:MaxJsonLength" value="20971520" />

a następnie utwórz dwie następujące klasy

public class JsonValueProviderConfig
{
    public static void Config(ValueProviderFactoryCollection factories)
    {
        var jsonProviderFactory = factories.OfType<JsonValueProviderFactory>().Single();
        factories.Remove(jsonProviderFactory);
        factories.Add(new CustomJsonValueProviderFactory());
    }
}

Jest to w zasadzie dokładna kopia domyślnej implementacji znaleziona w, System.Web.Mvcale z dodaną konfigurowalną wartością ustawienia web.config aspnet:MaxJsonLength.

public class CustomJsonValueProviderFactory : ValueProviderFactory
{

    /// <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 = CustomJsonValueProviderFactory.GetDeserializedObject(controllerContext);
        if (deserializedObject == null)
            return null;

        Dictionary<string, object> strs = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
        CustomJsonValueProviderFactory.AddToBackingStore(new CustomJsonValueProviderFactory.EntryLimitedDictionary(strs), string.Empty, deserializedObject);

        return new DictionaryValueProvider<object>(strs, CultureInfo.CurrentCulture);
    }

    private static object GetDeserializedObject(ControllerContext controllerContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            return null;

        string fullStreamString = (new StreamReader(controllerContext.HttpContext.Request.InputStream)).ReadToEnd();
        if (string.IsNullOrEmpty(fullStreamString))
            return null;

        var serializer = new JavaScriptSerializer()
        {
            MaxJsonLength = CustomJsonValueProviderFactory.GetMaxJsonLength()
        };
        return serializer.DeserializeObject(fullStreamString);
    }

    private static void AddToBackingStore(EntryLimitedDictionary backingStore, string prefix, object value)
    {
        IDictionary<string, object> strs = value as IDictionary<string, object>;
        if (strs != null)
        {
            foreach (KeyValuePair<string, object> keyValuePair in strs)
                CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakePropertyKey(prefix, keyValuePair.Key), keyValuePair.Value);

            return;
        }

        IList lists = value as IList;
        if (lists == null)
        {
            backingStore.Add(prefix, value);
            return;
        }

        for (int i = 0; i < lists.Count; i++)
        {
            CustomJsonValueProviderFactory.AddToBackingStore(backingStore, CustomJsonValueProviderFactory.MakeArrayKey(prefix, i), lists[i]);
        }
    }

    private class EntryLimitedDictionary
    {
        private static int _maximumDepth;

        private readonly IDictionary<string, object> _innerDictionary;

        private int _itemCount;

        static EntryLimitedDictionary()
        {
            _maximumDepth = CustomJsonValueProviderFactory.GetMaximumDepth();
        }

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

        public void Add(string key, object value)
        {
            int num = this._itemCount + 1;
            this._itemCount = num;
            if (num > _maximumDepth)
            {
                throw new InvalidOperationException("The length of the string exceeds the value set on the maxJsonLength property.");
            }
            this._innerDictionary.Add(key, value);
        }
    }

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

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

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

    private static int GetMaxJsonLength()
    {
        int num;
        NameValueCollection appSettings = ConfigurationManager.AppSettings;
        if (appSettings != null)
        {
            string[] values = appSettings.GetValues("aspnet:MaxJsonLength");
            if (values != null && values.Length != 0 && int.TryParse(values[0], out num))
            {
                return num;
            }
        }
        return 1000;
    }
}
Maxim Gerszkowicz
źródło
1
Dzięki, to działa ... Wielkie dzięki @Maxim Gershkovich
Jasper Manickaraj
1

Rozwiązanie dla WebForms UpdatePanel:

Dodaj ustawienie do Web.config:

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

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

ScriptRegistrationManager klasa zawiera następujący kod:

// 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);
Der_Meister
źródło
1

Nie potrzebujemy żadnych zmian po stronie serwera. możesz to naprawić tylko modyfikując za pomocą pliku web.config Pomogło mi to. wypróbuj to

<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>

Isanka Thalagala
źródło
0

posługiwać się lib\Newtonsoft.Json.dll

public string serializeObj(dynamic json) {        
    return JsonConvert.SerializeObject(json);
}
Buddhika De Silva
źródło
0

Naprawa dla ASP.NET MVC: jeśli chcesz to naprawić tylko dla określonej akcji powodującej problem, napisz następujący kod:

public JsonResult GetBigJson()
{
    var someBigObject = GetBigObject();
    return Json(someBigObject);
}

możesz to zmienić:

public JsonResult GetBigJson()
{
    var someBigObject = GetBigObject();
    return new JsonResult()
    {
        Data = someBigObject,
        JsonRequestBehavior = JsonRequestBehavior.DenyGet,
        MaxJsonLength = int.MaxValue
    };
}

A funkcjonalność powinna być taka sama, możesz po prostu zwrócić większy JSON jako odpowiedź.


Objaśnienie oparte na kodzie źródłowym ASP.NET MVC: możesz sprawdzić, co Controller.Jsonrobi metoda w kodzie źródłowym ASP.NET MVC

protected internal JsonResult Json(object data)
{
    return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
}

Wywołuje inną Controller.Jsonmetodę:

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult
    {
        Data = data,
        ContentType = contentType,
        ContentEncoding = contentEncoding,
        JsonRequestBehavior = behavior
    };
}

gdzie są przekazywane contentTypei contentEncodingobiekt null. Więc w zasadzie wywołanie return Json(object)kontrolera jest równoważne z wywołaniem return new JsonResult { Data = object, JsonRequestBehavior = sonRequestBehavior.DenyGet }. Możesz użyć drugiego formularza i sparametryzować JsonResult.

Co się stanie, gdy ustawisz MaxJsonLengthwłaściwość (domyślnie jest ona pusta)? Jest przekazywany do JavaScriptSerializer.MaxJsonLengthwłaściwości, a następnie wywoływanaJavaScriptSerializer.Serialize jest metoda :

JavaScriptSerializer serializer = new JavaScriptSerializer();
if (MaxJsonLength.HasValue)
{
    serializer.MaxJsonLength = MaxJsonLength.Value;
}

if (RecursionLimit.HasValue)
{
    serializer.RecursionLimit = RecursionLimit.Value;
}

response.Write(serializer.Serialize(Data));

A jeśli nie ustawisz MaxJsonLenghtwłaściwości serializatora, wówczas przyjmuje ona wartość domyślną, która wynosi zaledwie 2 MB.

Mariusz Pawelski
źródło
-2

jeśli ta wartość maxJsonLength jest liczbą int, to jak duża jest jej int 32bit / 64bit / 16bit .... chcę tylko mieć pewność, jaką maksymalną wartość mogę ustawić jako moją maksymalną długość

<scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
        </webServices>
    </scripting>
mpho Isaac Molelle
źródło
-4

Nie musisz robić z web.config Możesz użyć krótkiej właściwości podczas wartości catch listy przechodzącej Na przykład zadeklaruj model jak

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
}

tutaj używam krótkich proporcji, takich jak BC = kod kreskowy BE = wydanie książki i tak dalej

Md Nazrul Islam
źródło
To nie pomoże, jeśli większość danych znajduje się w wartościach właściwości
Okno