Bisakah saya menetapkan panjang tak terbatas untuk maxJsonLength di web.config?

663

Saya menggunakan fitur pelengkapan otomatis jQuery. Ketika saya mencoba untuk mengambil daftar lebih dari 17000 catatan (masing-masing tidak akan memiliki lebih dari 10 karakter), itu melebihi panjang dan melemparkan kesalahan:

Informasi pengecualian:
Jenis pengecualian: InvalidOperationException
Pesan pengecualian: Kesalahan selama serialisasi atau deserialisasi menggunakan JSON JavaScriptSerializer. Panjang string melebihi nilai yang ditetapkan pada properti maxJsonLength.

Bisakah saya menetapkan panjang tak terbatas untuk maxJsonLengthmasuk web.config? Jika tidak, berapa panjang maksimum yang dapat saya atur?

Prasad
sumber
1
Sesuatu untuk disebutkan yang mungkin cukup jelas jadi tolong permisi jika Anda sudah memikirkannya; string Json juga termasuk tanda kurung keriting di sekitar setiap catatan, tanda kutip di sekitar setiap nama bidang [dan nilai], serta nama bidang dan nilai. Jadi mungkin berguna untuk menetapkan nama bidang sebagai karakter tunggal dan juga memastikan bahwa jika nilainya bukan string, Anda mengatur jenis bidang dengan benar sehingga tidak mengandung tanda kutip.
MichaelJTaylor

Jawaban:

720

CATATAN: jawaban ini hanya berlaku untuk layanan Web, jika Anda mengembalikan JSON dari metode Controller, pastikan Anda membaca jawaban SO ini di bawah ini juga: https://stackoverflow.com/a/7207539/1246870


The MaxJsonLength properti tidak bisa terbatas, adalah properti integer yang defaultnya 102400 (100k).

Anda dapat mengatur MaxJsonLengthproperti di web.config Anda:

<configuration> 
   <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
</configuration> 
CMS
sumber
153
Ini adalah bilangan bulat sehingga nilai maksimal yang dapat Anda tetapkan adalah: 2147483644
David Espart
58
@despart: Maksud Anda 2 147 483
647.
6
@ kmcc049, nilai IMO tidak salah karena jika Anda melihat pertanyaan, OP tidak bertanya "apa nilai default maxJsonLength?" (BTW, jawaban terbanyak kedua adalah menjawab ini, pertanyaan yang salah), ia mencoba mengatur properti ini menjadi "tidak terbatas", tetapi karena merupakan Integer, nilai maksimum yang mungkin 2147483647ditunjukkan oleh @depsart dan @ Descár tunjukkan.
CMS
11
Hebat tapi perhatikan jawaban @David Murdoch di bawah ini jika Anda mengalami masalah ini saat menggunakan MVC return Json()atau yang lainnya
BritishDeveloper
3
@ Dercsár: apa gunanya? 2147483644 adalah bilangan bulat terbesar yang dapat habis dibagi dengan 1024.
naveen
461

Jika Anda menggunakan MVC 4 , pastikan untuk memeriksa jawaban ini juga.


Jika Anda masih menerima kesalahan:

  • setelah menyetel maxJsonLengthproperti ke nilai maksimumnya di web.config
  • dan Anda tahu bahwa panjang data Anda kurang dari nilai ini
  • dan Anda tidak menggunakan metode layanan web untuk serialisasi JavaScript

masalah Anda kemungkinan besar adalah:

Nilai properti MaxJsonLength hanya berlaku untuk instance JavaScriptSerializer internal yang digunakan oleh lapisan komunikasi asinkron untuk memanggil metode layanan Web. ( MSDN: Properti ScriptingJsonSerializationSection.MaxJsonLength )

Pada dasarnya, "internal" JavaScriptSerializermenghargai nilai maxJsonLengthketika dipanggil dari metode web; penggunaan langsung dari JavaScriptSerializer(atau penggunaan melalui metode-aksi / Pengendali MVC) tidak menghormati maxJsonLengthproperti, setidaknya tidak dari systemWebExtensions.scripting.webServices.jsonSerializationbagian web.config.

Sebagai solusinya, Anda dapat melakukan hal berikut di dalam Pengontrol Anda (atau di mana pun juga):

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;

Jawaban ini adalah interpretasi saya atas jawaban forum asp.net ini .

David Murdoch
sumber
5
Jawaban Anda sangat membantu karena saya menggunakan Json()metode hasil tindakan di asp.net mvc.
jessegavin
3
Yap saya juga seorang Json () menderita. Terima kasih!
Pengembang Inggris
3
Meskipun benar-benar benar dan pantas untuk tempatnya, ini adalah salah satu pertanyaan di mana ada baiknya membaca melewati jawaban atas :). Terima kasih!
Nigel
3
Jika Anda menggunakan MVC4 silakan lihat jawaban @fanisch juga.
Beyers
4
Bagaimana Deserialisasi? Saya bertemu kesalahan ini di model tindakan mengikat.
guogangj
345

Di MVC 4 Anda dapat melakukan:

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

di controller Anda.

Tambahan:

Bagi siapa pun yang bingung dengan parameter yang perlu Anda tentukan, panggilan bisa terlihat seperti ini:

Json(
    new {
        field1 = true,
        field2 = "value"
        },
    "application/json",
    Encoding.UTF8,
    JsonRequestBehavior.AllowGet
);
fanisch
sumber
6
Saya dapat mengkonfirmasi bahwa di atas berfungsi seperti pesona di MVC 4, terima kasih fanisch.
Beyers
9
Saya dapat mengkonfirmasi juga. Menempatkan kode ini di dalam basis controller jelas merupakan pendekatan paling bersih yang diusulkan.
parlemen
15
Ini juga berfungsi dengan hanya menambahkan "MaxJsonLength = Int32.MaxValue" ke hasil tindakan individu. Dalam hal perubahan tidak diinginkan controller atau proyek lebar.
Hypnovirus
3
Ini jawaban terbaik. MaxJsonLength dapat dikonfigurasi per controller.
liang
3
PERINGATAN: solusi ini menonaktifkan kompresi (jika diminta) dari respons. Tambahkan filter ini pada tindakan Anda: stackoverflow.com/questions/3802107/…
Gorgi Rankovski
60

Anda dapat mengkonfigurasi panjang maks untuk permintaan json di file web.config Anda:

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

Nilai default untuk maxJsonLength adalah 102400 . Untuk detail lebih lanjut, lihat halaman MSDN ini: http://msdn.microsoft.com/en-us/library/bb763183.aspx

M4N
sumber
1
Berapakah nilai yang disimpan dalam bilangan bulat ini mewakili? Apakah ini semacam hitungan karakter? Saya kira yang saya tanyakan adalah, mengapa integer digunakan? Terima kasih!
eaglei22
@ eaglei22 angka tersebut menunjukkan jumlah byte yang dapat digunakan untuk maxJsonLength. Seperti yang disebutkan M4N, 102400 adalah default (100KB).
Jacob Plonke
ini tidak berfungsi untuk saya dan saya tidak menggunakan layanan web.
kalai
42

jika Anda masih mendapatkan kesalahan setelah pengaturan web.config seperti berikut:

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

Saya menyelesaikannya dengan mengikuti:

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

Saya harap ini akan membantu.

Ravi Anand
sumber
2
Mengatur maxJsonLength di web.config tidak tepat, pengaturan jsonResult.MaxJsonLength harus cukup (setidaknya itu untuk saya (MVC5))
hormberg
Ini bagus karena ini bukan perubahan global.
rob_james
40

Saya mengalami masalah ini dalam Formulir Web ASP.NET. Itu benar-benar mengabaikan pengaturan file web.config jadi saya melakukan ini:

        JavaScriptSerializer serializer = new JavaScriptSerializer();

        serializer.MaxJsonLength = Int32.MaxValue; 

        return serializer.Serialize(response);

Tentu saja secara keseluruhan ini adalah praktik yang mengerikan. Jika Anda mengirim data sebanyak ini dalam panggilan layanan web, Anda harus melihat pendekatan yang berbeda.

Kutu
sumber
1
apakah ini berhasil untukmu? di mana Anda menempatkan kode ini?
user1012598
Masalah kami adalah karena kami memiliki textarea yang memungkinkan untuk HTML dan orang-orang menanamkan gambar sebagai HTML yang menyebabkan entri menjadi sangat besar dan serializer JSON gagal. Saya kira jika itu bisa dilakukan pengguna akan melakukannya ...
Marko
Tolong jelaskan di mana kita harus meletakkan kode ini ... @Flea
Koray Durudogan
@ KorayDurudogan - Saya menempatkan ini dalam metode Ajax yang mengembalikan respons, jadi di controller saya. Semoga itu bisa membantu!
Flea
Saya tidak menantang respons Anda, tetapi mencoba untuk mendapatkan ide yang lebih baik tentang pendekatan apa yang lebih baik. Saya punya pertanyaan yang tergantung pada kriteria pengguna akan menentukan ukuran hasil. Saya mengembalikan JsonResult, Apakah penting jika saya mengembalikan file excel?
eaglei22
22

Aku telah memperbaikinya.

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

Ini bekerja dengan sangat baik.

Mario Arrieta
sumber
Luar biasa! Ini adalah satu-satunya solusi yang bekerja untuk saya dan lebih baik karena itu bukan perubahan global. Terima kasih!
Sealer_05
20

Saya mengikuti jawaban vestigal dan mendapatkan solusi ini:

Ketika saya perlu memposting json besar ke aksi di controller, saya akan mendapatkan kesalahan "terkenal selama deserialisasi menggunakan JSON JavaScriptSerializer. Panjang string melebihi nilai yang ditetapkan pada properti maxJsonLength. \ R \ nParameter name: input penyedia nilai ".

Apa yang saya lakukan adalah membuat ValueProviderFactory, LargeJsonValueProviderFactory, dan atur MaxJsonLength = Int32.MaxValue dalam metode 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;
     }
  }
}

Kemudian, dalam metode Application_Start dari Global.asax.cs, ganti ValueProviderFactory dengan yang baru:

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);
}
MFA
sumber
1
Saya melakukan segala hal yang saya bisa, hanya jawaban Anda yang menyelamatkan hari saya, ini seharusnya jawaban yang diterima
Muhammad Waqas Aziz
Dengan kode ini kita dapat menimpa batas MVC controller max json Deserializetion sebesar 4 mb, tetapi apakah ada cara untuk mengganti kontroler web-api max json Batas deserializetion
Muhammad Waqas Aziz
17

jika, setelah menerapkan penambahan di atas ke dalam web.config Anda, Anda mendapatkan "bagian konfigurasi yang tidak dikenal system.web.extensions." galat lalu coba tambahkan ini ke web.config Anda di <ConfigSections>bagian:

            <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
sumber
4
Saya mengalami masalah ini. Namun, jawaban ini tidak berhasil untuk saya. Alih-alih menambahkan elemen <sectionGroup> yang dijelaskan di sini, saya hanya memindahkan seluruh blok <system.web.extensions> yang baru ditambahkan ke bagian paling akhir dari web.config saya ... tepat sebelum </configuration>. Lalu berhasil.
ClearCloud8
Ini membantu, tetapi dalam situasi saya, saya perlu mengubah baris keempat Anda <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>, seperti yang terlihat di halaman ini: forums.asp.net/t/1446510.aspx/1
Nathan
@ ClearCloud8 Segera sebarkan komentar di halaman ini.
Jack Nutkins
11

Anda dapat menulis baris ini ke Controller

json.MaxJsonLength = 2147483644;

Anda juga dapat menulis baris ini web.config

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

`

Agar aman, gunakan keduanya.

Pankaj Sapkal
sumber
10

Jika Anda mendapatkan kesalahan ini dari MiniProfiler di MVC maka Anda dapat meningkatkan nilainya dengan mengatur properti MiniProfiler.Settings.MaxJsonResponseSizeke nilai yang diinginkan. Secara default, alat ini tampaknya mengabaikan nilai yang diatur dalam konfigurasi.

MiniProfiler.Settings.MaxJsonResponseSize = 104857600;

Atas perkenan mvc-mini-profiler .

wolfyuk
sumber
10

Cukup atur MaxJsonLength proprty dalam metode Action MVC

JsonResult json= Json(classObject, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
Aftab Ahmed Kalhoro
sumber
9

Saya sarankan mengaturnya ke Int32.MaxValue.

JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
Santhosh
sumber
9

Bagaimana dengan sihir atribut?

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

Kemudian Anda bisa menerapkannya secara global menggunakan konfigurasi filter global atau pengontrol / tindakan-bijaksana.

Balázs
sumber
Jawaban yang bagus Penggunaan atribut khusus yang bagus. Ingin tahu apakah ada alasan (teknis) khusus yang Anda tetapkan default ke 10 MB senilai satu byte karakter bukan Max (int.MaxValue)?
Josh
@ Ya Tidak, tidak ada alasan khusus untuk itu.
Balázs
5

Pertanyaannya adalah apakah Anda benar-benar perlu mengembalikan catatan 17k? Bagaimana Anda berencana menangani semua data di browser? Pengguna tidak akan menggulir 17.000 baris.

Pendekatan yang lebih baik adalah dengan hanya mengambil catatan "beberapa teratas" dan memuat lebih banyak seperti yang diperlukan.

Chetan Sastry
sumber
1
Daftar default dari json akan memberikan catatan 17k. Tetapi fitur pelengkapan otomatis hanya akan mencantumkan catatan yang cocok dengan karakter yang diketik pengguna, sehingga tidak perlu lagi menggulir daftar. JADI yang saya butuhkan adalah mengatur panjang tidak terbatas untuk maxJsonLength yang dapat membuat serial data 17k.
Prasad
6
Anda dapat menggunakan kombinasi pemfilteran sisi server dan klien. Mungkin sulit untuk memfilter semua data di sisi klien, belum lagi latensi jaringan.
Chetan Sastry
1
Setelah tiba di masalah yang sama beberapa waktu lalu, saya memilih untuk mengimplementasikan handler "onsearch" untuk autocomplete, dan meminta layanan web melewati teks "search" dan melakukan kueri Top10 menggunakan kriteria pencarian sebagai filter. Ini berarti lebih banyak permintaan ajax individual, yang hanya mendapatkan daftar lengkap tentang pemuatan halaman, tetapi juga berarti bahwa semua permintaan / respons jauh lebih kecil.
Mike U
3

Anda dapat mengaturnya di konfigurasi seperti yang dikatakan orang lain, atau Anda dapat mengaturnya pada instance serializer seperti:

var js = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
Caleb Postlethwait
sumber
3

Bagi mereka yang mengalami masalah dengan MVC3 dengan JSON yang secara otomatis deserialized untuk pengikat model dan terlalu besar, berikut ini solusinya.

  1. Salin kode untuk kelas JsonValueProviderFactory dari kode sumber MVC3 ke kelas baru.
  2. Tambahkan baris untuk mengubah panjang JSON maksimum sebelum objek deserialized.
  3. Ganti kelas JsonValueProviderFactory dengan kelas Anda yang baru dan telah dimodifikasi.

Terima kasih kepada http://blog.naver.com/techshare/100145191355 dan https://gist.github.com/DalSoft/1588818 karena mengarahkan saya ke arah yang benar untuk melakukan hal ini. Tautan terakhir di situs pertama berisi kode sumber lengkap untuk solusi.

vestigal
sumber
3

Jika Anda mengalami masalah semacam ini di Tampilan, Anda dapat menggunakan metode di bawah ini untuk menyelesaikannya. Di sini saya menggunakan paket Newtonsoft .

@using Newtonsoft.Json
<script type="text/javascript">
    var partData = @Html.Raw(JsonConvert.SerializeObject(ViewBag.Part));
</script>
dush88c
sumber
Apakah ini berarti saya tidak perlu khawatir tentang panjang maks jika saya menggunakan Json.NET? Saya tidak berpikir ada cara untuk mengatur panjang max di Json.NET jadi saya berharap itu hanya bekerja di luar kotak.
kimbaudi
1
Jawaban Luar Biasa terima kasih! Ini juga berfungsi ketika saya mencoba memuat objek.
user1299379
3
 JsonResult result = Json(r);
 result.MaxJsonLength = Int32.MaxValue;
 result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
 return result;
Aikansh Mann
sumber
2

Tampaknya tidak ada nilai "tidak terbatas". Standarnya adalah 2097152 karakter, yang setara dengan 4 MB data string Unicode.

Seperti yang telah diamati, 17.000 catatan sulit digunakan dengan baik di peramban. Jika Anda menyajikan tampilan agregat, mungkin jauh lebih efisien untuk melakukan agregasi di server dan hanya mentransfer ringkasan di browser. Misalnya, pertimbangkan peramban sistem file, kami hanya melihat bagian atas pohon, lalu memancarkan permintaan lebih lanjut saat kami menelusuri. Jumlah catatan yang dikembalikan dalam setiap permintaan relatif kecil. Presentasi tampilan pohon dapat bekerja dengan baik untuk set hasil yang besar.

djna
sumber
3
agak anehnya default dalam kode (JavaScriptSerializer baru ()). MaxJsonLength adalah 2097152 byte tetapi layanan web ResponseFormatJson adalah 102400 byte kecuali ditetapkan secara eksplisit.
merampok
2

Baru saja berlari ke ini. Saya mendapatkan lebih dari 6.000 catatan. Saya baru saja memutuskan untuk melakukan paging. Seperti pada, saya menerima nomor halaman di titik akhir MVC JsonResult saya, yang default ke 0 sehingga tidak perlu, seperti:

public JsonResult MyObjects(int pageNumber = 0)

Maka alih-alih mengatakan:

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

Saya katakan:

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

Ini sangat sederhana. Kemudian, dalam JavaScript, alih-alih ini:

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

Saya malah mengatakan:

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

Dan tambahkan catatan Anda pada apa pun yang Anda lakukan dengan mereka di tempat pertama. Atau tunggu sampai semua panggilan selesai dan hasil bersama-sama rusak.

vbullinger
sumber
2

Saya memecahkan masalah dengan menambahkan kode ini:

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
sumber
Ini tampaknya seperti solusi peretasan tetapi pendekatan yang menarik terlepas. Saya merasa ini berguna, terima kasih! Bagi saya di apsnet mvc 5 controller saya harus menghapus 'Current' dari namespace. Saya membuat beberapa penyesuaian: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();
ooXei1sh
2

Alternatif ASP.NET MVC 5 Fix:

(Tambang mirip dengan jawaban MFC di atas dengan beberapa perubahan kecil)

Saya belum siap untuk berubah ke Json.NET dulu dan dalam kasus saya kesalahan terjadi selama permintaan. Pendekatan terbaik dalam skenario saya adalah memodifikasi aktual JsonValueProviderFactoryyang berlaku untuk memperbaiki proyek global dan dapat dilakukan dengan mengedit global.csfile seperti itu.

JsonValueProviderConfig.Config(ValueProviderFactories.Factories);

tambahkan entri web.config:

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

dan kemudian buat dua kelas berikut

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

Ini pada dasarnya adalah salinan persis dari implementasi default yang ditemukan di System.Web.Mvctetapi dengan penambahan nilai pengaturan web.config yang dapat dikonfigurasi 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 Gershkovich
sumber
1
Terima kasih itu bekerja ... Terima kasih banyak @ Maxim Gershkovich
Jasper Manickaraj
1

Solusi untuk WebForms UpdatePanel:

Tambahkan pengaturan ke Web.config:

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

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

ScriptRegistrationManager kelas berisi kode berikut:

// 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
sumber
1

Kami tidak membutuhkan perubahan sisi server. Anda dapat memperbaiki ini hanya memodifikasi oleh file web.config Ini membantu saya. coba ini

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

menggunakan lib\Newtonsoft.Json.dll

public string serializeObj(dynamic json) {        
    return JsonConvert.SerializeObject(json);
}
Buddhika De Silva
sumber
0

Perbaiki untuk ASP.NET MVC: jika Anda ingin memperbaikinya hanya untuk tindakan tertentu yang menyebabkan masalah maka kode seperti ini:

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

Anda dapat mengubah ini:

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

Dan fungsinya harus sama, Anda bisa mengembalikan JSON yang lebih besar sebagai respons.


Penjelasan berdasarkan kode sumber ASP.NET MVC: Anda dapat memeriksa Controller.Jsonmetode apa yang dilakukan dalam kode sumber ASP.NET MVC

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

Itu memanggil Controller.Jsonmetode lain :

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

di mana berlalu contentTypedan contentEncodingobjek berada null. Jadi pada dasarnya memanggil return Json(object)controller sama dengan memanggil return new JsonResult { Data = object, JsonRequestBehavior = sonRequestBehavior.DenyGet }. Anda dapat menggunakan formulir dan parameter keduaJsonResult .

Jadi apa yang terjadi ketika Anda menetapkan MaxJsonLengthproperti (secara default itu nol)? Itu diturunkan ke JavaScriptSerializer.MaxJsonLengthproperti dan kemudian JavaScriptSerializer.Serializemetode disebut :

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

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

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

Dan ketika Anda tidak mengatur MaxJsonLenghtproperti serializer maka dibutuhkan nilai default yang hanya 2MB.

Mariusz Pawelski
sumber
-2

jika nilai maxJsonLength ini adalah int maka seberapa besar int 32bit / 64bit / 16bit .... saya hanya ingin memastikan whats nilai maksimum yang dapat saya tetapkan sebagai maxJsonLength saya

<scripting>
        <webServices>
            <jsonSerialization maxJsonLength="2147483647">
            </jsonSerialization>
        </webServices>
    </scripting>
mpho isaac Molelle
sumber
-4

Anda tidak perlu melakukan dengan web.config Anda dapat menggunakan properti pendek selama nilai tangkapan dari daftar yang lewat Misalnya mendeklarasikan model seperti

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
}

di sini saya menggunakan proporsi pendek seperti BC = barcode BE = edisi buku dan sebagainya

Md Nazrul Islam
sumber
Ini tidak akan membantu jika sebagian besar data ada dalam nilai properti
Window