জাভাস্ক্রিপ্টসিরাইজারের সময় এএসপি.নেট এমভিসি-তে ম্যাক্সজেসনলেন্থ ব্যতিক্রম


122

আমার এক নিয়ন্ত্রকের ক্রিয়ায় আমি JsonResultএকটি গ্রিড পূরণ করতে খুব বড় ফিরছি।

আমি নিম্নলিখিত InvalidOperationExceptionব্যতিক্রম পাচ্ছি :

জাসন জাভাস্ক্রিপ্টসরিয়ালাইজার ব্যবহার করে সিরিয়ালাইজেশন বা ডিসরিয়ালাইজেশন করার সময় ত্রুটি। স্ট্রিংয়ের দৈর্ঘ্য সর্বোচ্চ জেসনলেন্থ সম্পত্তিতে সেট মানটি ছাড়িয়ে গেছে।

দুর্ভাগ্যক্রমে দুর্ভাগ্যক্রমে maxJsonLengthসম্পত্তিটিকে web.configউচ্চতর মানতে সেট করা কোনও প্রভাব দেখায় না।

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

আমি এই এসও উত্তরে উল্লিখিত স্ট্রিং হিসাবে এটি ফিরে যেতে চাই না ।

আমার গবেষণায় আমি এই ব্লগ পোস্টটি জুড়ে এসেছি যেখানে এই আচরণটি বাইপাস করার জন্য নিজস্ব ActionResult(উদাহরণস্বরূপ LargeJsonResult : JsonResult) লেখার পরামর্শ দেওয়া হয়।

তাহলে কি এই একমাত্র সমাধান?
এটি কি এএসপি.নেট এমভিসিতে কোনও বাগ আছে?
আমি কিছু অনুপস্থিত করছি?

যে কোন সাহায্যই সর্বাধিক প্রশংসিত হত।


2
আপনার সমাধানগুলি এমভিসি 3 তে কাজ করে
ম্যাটটিএসপি

1
আপনি কি নিশ্চিত? এটি একটি পুরানো প্রশ্ন এবং আমি মনে করতে পারি না তবে স্পষ্টতই আমি এটিকে এমভিসি 3 হিসাবে ট্যাগ করেছি। দুর্ভাগ্যক্রমে আমি সংস্করণটি / তারিখটি দেখতে পাচ্ছি না যখন এটি স্থির / বন্ধ হয়ে গেছে: aspnet.codeplex.com/workitem/3436
মার্টিন

1
অবশ্যই, আমি এমভিসি 3 এর সাথে কাজ করছি এবং এটি কাজ করে। এবং সৌভাগ্যক্রমে, কারণ এমভিসি 3 তে আপনার কাছে "ম্যাক্সজেসনলেন্থ" বৈশিষ্ট্য গৃহীত উত্তরে নেই।
ম্যাটটিএসপি

উত্তর:


228

এটি এমভিসি 4 এ স্থির করা হয়েছে বলে মনে হয়।

আপনি এটি করতে পারেন, যা আমার পক্ষে ভাল কাজ করেছে:

public ActionResult SomeControllerAction()
{
  var jsonResult = Json(veryLargeCollection, JsonRequestBehavior.AllowGet);
  jsonResult.MaxJsonLength = int.MaxValue;
  return jsonResult;
}

আমি একটি ভিউব্যাগ.মাইজেসন স্ট্রিং সম্পত্তিটিতে একটি জসন স্ট্রিং স্থাপন করছি তবে জাভাস্ক্রিপ্ট লাইনের নিম্নলিখিত সময়ে রানটাইমে আমার দৃষ্টিতে একই ত্রুটি পেয়েছি: var myJsonObj = @ এইচটিএমএল.রউ (জসন.এনকোড (ভিউব্যাগ.মাইজসনস্ট্রিং));
ফয়সাল এমকিউ

1
আরে @ ওরিওনডেবার্ডস, @ জিজি, @ মার্টিন বুবারল আমি একই ম্যাক্সজেসন ইস্যুটির মুখোমুখি হয়েছি কিন্তু নিয়ামককে ডেটা পোস্ট করার সময়, আমি কীভাবে এটি পরিচালনা করতে পারি, আমি এই সম্পর্কে অনুসন্ধানে এতটা সময় ব্যয় করেছি। কোন সাহায্যের কৃতজ্ঞতা হবে।
katmanco

আমার ক্ষেত্রে কাজ হয়নি কারণ জসন সংগ্রহের সিরিয়ালাইজ করার আগে আমাকে ম্যাকজেসনলেন্থ সেট করতে হয়েছিল।
সিজার লিয়ন

আমার ক্ষেত্রে সূক্ষ্মভাবে কাজ করে, চূড়ান্ত ব্যবহারকারীর জন্য উপস্থাপনের জন্য ডেটাটেবলের "চিত্রগুলি" থাকায় আমাকে এটি প্রয়োগ করতে হয়েছিল। এটি ছাড়া, কোনও বোধগম্য বার্তা ছাড়াই ক্র্যাশ।
মাউরো ক্যান্ডিডো

33

আপনি এখানে সাবক্লাসিংয়ের পরিবর্তে প্রস্তাবিতContentResult হিসাবে ব্যবহার করতে পারেন ।JsonResult

var serializer = new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue, RecursionLimit = 100 };

return new ContentResult()
{
    Content = serializer.Serialize(data),
    ContentType = "application/json",
};

2
আমার ক্ষেত্রে, একটি নিক্ষিপ্ত অ্যাপে কাজ করা, এই সমাধানটি আমার পক্ষে সবচেয়ে ভাল কাজ করেছে। jsonresult বাস্তবায়ন সংরক্ষণ। ধন্যবাদ!
ক্রিস্টো

25

দুর্ভাগ্যক্রমে ওয়েবকনফিগ সেটিং ডিফল্ট জসনআরসাল্ট বাস্তবায়ন দ্বারা উপেক্ষা করা হয়েছে । সুতরাং আমি অনুমান করি যে এই সমস্যাটি কাটিয়ে উঠতে আপনাকে একটি কাস্টম জসন ফলাফল প্রয়োগ করতে হবে।


22

কাস্টম ক্লাসের দরকার নেই। এই সমস্ত প্রয়োজন:

return new JsonResult { Data = Result, MaxJsonLength = Int32.MaxValue };

Resultআপনি যে ডেটাটি সিরিয়াল করতে চান তা কোথায় ?


ত্রুটি 137 'System.Web.Mvc.JsonResult' 'MaxJsonLength' এর জন্য একটি সংজ্ঞা ধারণ করে না
পশুর পদচিহ্ন

এটি আমার পক্ষে কাজ করেছে, তবুও এটি যুক্ত করার দরকার ছিল: JsonRequestBehavior = JsonRequestBehavior.AllowGet
ডাবম্যান

5

যদি স্ট্রিংটি উত্পন্ন করতে Json.NET ব্যবহার jsonকরে তবে এর MaxJsonLengthমান সেট করার দরকার নেই ।

return new ContentResult()
{
    Content = Newtonsoft.Json.JsonConvert.SerializeObject(data),
    ContentType = "application/json",
};

4

আমি এই লিঙ্কটি অনুসরণ করে সমস্যাটি সমাধান করেছি

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

3

আমি অবাক হয়েছি যে কেউ ফলাফল ফিল্টার ব্যবহার করার পরামর্শ দেয়নি। অ্যাকশন / রেজাল্ট পাইপলাইনে বিশ্বব্যাপী এটাই সবচেয়ে পরিষ্কার উপায়:

public class JsonResultFilter : IResultFilter
{
    public int? MaxJsonLength { get; set; }

    public int? RecursionLimit { get; set; }

    public void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (filterContext.Result is JsonResult jsonResult)
        {
            // override properties only if they're not set
            jsonResult.MaxJsonLength = jsonResult.MaxJsonLength ?? MaxJsonLength;
            jsonResult.RecursionLimit = jsonResult.RecursionLimit ?? RecursionLimit;
        }
    }

    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
    }
}

তারপরে, এই শ্রেণীর উদাহরণ ব্যবহার করে নিবন্ধ করুন GlobalFilters.Filters:

GlobalFilters.Filters.Add(new JsonResultFilter { MaxJsonLength = int.MaxValue });

2

আপনি আপনার লিনকিউ এক্সপ্রেশনটি কেবলমাত্র সেই ক্ষেত্রের প্রয়োজন যা নির্ধারণ করতে পারেন।

উদাহরণ। ধারণা করুন যে আপনার আইডি, নাম, ফোন এবং ছবি (বাইট অ্যারে) সহ একটি মডেল রয়েছে এবং একটি নির্বাচিত তালিকায় জসন থেকে লোড করা দরকার।

লিনকিউ প্রশ্ন:

var listItems = (from u in Users where u.name.Contains(term) select u).ToList();

এখানে সমস্যাটি হ'ল " সিলেক্ট ইউ " যা সমস্ত ক্ষেত্র পেয়ে। সুতরাং, আপনার যদি বড় ছবি থাকে তবে বুম।

কীভাবে সমাধান করব? খুব, খুব সহজ।

var listItems = (from u in Users where u.name.Contains(term) select new {u.Id, u.Name}).ToList();

সেরা অনুশীলনগুলি কেবলমাত্র সেই ক্ষেত্রটি নির্বাচন করুন যা আপনি ব্যবহার করবেন।

মনে রাখুন। এটি একটি সহজ টিপ, তবে অনেক এএসপি.নেট এমভিসি বিকাশকারীকে সহায়তা করতে পারে।


1
আমি ধরে নেব না যে এই ক্ষেত্রে ব্যবহারকারী তাদের ডেটা ফিল্টার করতে চায়। কিছু লোকের ডেটাবেস থেকে প্রচুর পরিমাণে সারি ফিরিয়ে আনার প্রয়োজনীয়তা রয়েছে ...
সাইমন নিকোলস

2

বিকল্প এএসপি.নেট এমভিসি 5 ফিক্স:

আমার ক্ষেত্রে অনুরোধের সময় ত্রুটি ঘটছিল। আমার দৃশ্যের সেরা পদ্ধতিকে আসলটি সংশোধন করা হচ্ছে JsonValueProviderFactoryযা বৈশ্বিক প্রকল্পের স্থিরতাকে প্রযোজ্য এবং global.csফাইলটি সম্পাদনা করে এটি করা যেতে পারে ।

JsonValueProviderConfig.Config(ValueProviderFactories.Factories);

একটি ওয়েব.কমফিগ এন্ট্রি যুক্ত করুন:

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

এবং তারপরে নিম্নলিখিত দুটি ক্লাস তৈরি করুন

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

এটি মূলত ডিফল্ট বাস্তবায়নের একটি সঠিক অনুলিপি System.Web.Mvcতবে একটি কনফিগারযোগ্য ওয়েব কোডফাইগ অ্যাপসেটিং মান যুক্ত করার সাথে পাওয়া যায় 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;
    }
}

তোমাকে অনেক ধন্যবাদ !
ল্যারিজ্জাটগ

1

উপরের কোনওটিই আমার পক্ষে কার্যকর হয়নি যতক্ষণ না আমি অ্যাকশন হিসাবে পরিবর্তন করি [HttpPost]। এবং এজ্যাক্স টাইপ হিসাবে তৈরি POST

    [HttpPost]
    public JsonResult GetSelectedSignalData(string signal1,...)
    {
         JsonResult result = new JsonResult();
         var signalData = GetTheData();
         try
         {
              var serializer = new System.Web.Script.Serialization.JavaScriptSerializer { MaxJsonLength = Int32.MaxValue, RecursionLimit = 100 };

            result.Data = serializer.Serialize(signalData);
            return Json(result, JsonRequestBehavior.AllowGet);
            ..
            ..
            ...

    }

এবং এজ্যাক্স কল হিসাবে

$.ajax({
    type: "POST",
    url: some_url,
    data: JSON.stringify({  signal1: signal1,.. }),
    contentType: "application/json; charset=utf-8",
    success: function (data) {
        if (data !== null) {
            setValue();
        }

    },
    failure: function (data) {
        $('#errMessage').text("Error...");
    },
    error: function (data) {
        $('#errMessage').text("Error...");
    }
});

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

এমভিসি 4 এ আমার জন্য স্থির ছিল।


0

আপনার কোডটি কোনও জসনআরসাল্ট অবজেক্ট ফেরত দেওয়ার আগে আপনাকে ম্যানুয়ালি কনফিগারেশন বিভাগটি পড়তে হবে। কেবলমাত্র একক লাইনে ওয়েবকনফিগ থেকে পড়ুন:

        var jsonResult = Json(resultsForAjaxUI);
        jsonResult.MaxJsonLength = (ConfigurationManager.GetSection("system.web.extensions/scripting/webServices/jsonSerialization") as System.Web.Configuration.ScriptingJsonSerializationSection).MaxJsonLength;
        return jsonResult;

নিশ্চিত হয়ে নিন যে আপনি ওয়েব কনফিগে কনফিগারেশন উপাদানটি সংজ্ঞায়িত করেছেন


0

এটি আমার জন্য কাজ করেছে

        JsonSerializerSettings json = new JsonSerializerSettings
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };
        var result = JsonConvert.SerializeObject(list, Formatting.Indented, json);
        return new JsonResult { Data = result, MaxJsonLength = int.MaxValue };

0

কিছুটা অন্য ক্ষেত্রে আছে - ক্লায়েন্ট থেকে সার্ভারে ডেটা প্রেরণ করা হয়। আপনি যখন নিয়ামক পদ্ধতি এবং মডেলটি ব্যবহার করছেন তখন বিশাল:

    [HttpPost]
    public ActionResult AddOrUpdateConsumerFile(FileMetaDataModelView inputModel)
    {
        if (inputModel == null) return null;
     ....
    }

সিস্টেমটি এই জাতীয় ব্যতিক্রম ছুঁড়ে ফেলেছে "জেএসএন জাভাস্ক্রিপ্টসরিয়ালাইজার ব্যবহার করে সিরিয়ালাইজেশন বা ডিসরিয়ালেসনের সময় ত্রুটি the স্ট্রিংটির দৈর্ঘ্য সর্বাধিক জেসনস্ল্যাংথ সম্পত্তিতে সেট মানের চেয়েও বেশি Para

এই ক্ষেত্রে সাহায্যের জন্য কেবলমাত্র ওয়েবকনফিগ সেটিংস পরিবর্তন করা যথেষ্ট নয়। আপনি অতিরিক্ত ডেটা মডেল আকারগুলি সমর্থন করার জন্য বা অনুরোধ থেকে ম্যানুয়ালি ডিজিটালাইজড মডেলটির জন্য এমভিসি জসন সিরিয়ালাইজারকে ওভাররাইড করতে পারেন। আপনার নিয়ামক পদ্ধতিটি হয়ে যায়:

   [HttpPost]
    public ActionResult AddOrUpdateConsumerFile()
    {
        FileMetaDataModelView inputModel = RequestManager.GetModelFromJsonRequest<FileMetaDataModelView>(HttpContext.Request);
        if (inputModel == null) return null;
        ......
    }

   public static T GetModelFromJsonRequest<T>(HttpRequestBase request)
    {
        string result = "";
        using (Stream req = request.InputStream)
        {
            req.Seek(0, System.IO.SeekOrigin.Begin);
            result = new StreamReader(req).ReadToEnd();
        }
        return JsonConvert.DeserializeObject<T>(result);
    }

0

আপনি এই কোডটি সিএসটিএমএলে রাখতে পারেন যদি আপনি নিয়ামক থেকে দর্শনটি ফিরে আসছেন এবং আপনি সিএসটিএমএল-তে জসনকে এনকোড করার সময় ব্যাগের ডেটার দৈর্ঘ্য বাড়াতে চান

@{
    var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
    jss.MaxJsonLength = Int32.MaxValue;
    var userInfoJson = jss.Serialize(ViewBag.ActionObj);
}

var dataJsonOnActionGrid1 = @Html.Raw(userInfoJson);

এখন, dataJsonOnActionGrid1 জেএস পৃষ্ঠায় অ্যাক্সেসযোগ্য এবং আপনি সঠিক ফলাফল পাবেন।

ধন্যবাদ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.