c# - একটি সার্কুলার রেফারেন্সটি সনাক্ত করা হয়েছিল যখন 'SubSonic.Schema'।




.net json (10)

আমি একটি সাধারণ JSON রিটার্ন করার চেষ্টা করছি কিন্তু আমার সমস্যা হচ্ছে আমার নীচেরটি আছে।

public JsonResult GetEventData()
{
    var data = Event.Find(x => x.ID != 0);
    return Json(data);
}

আমি এই প্রশ্নের শিরোনাম হিসাবে দেখানো ব্যতিক্রম সঙ্গে একটি HTTP 500 পেতে। আমিও চেষ্টা করেছি

var data = Event.All().ToList()

যে একই সমস্যা দিয়েছে।

এই একটি বাগ বা আমার বাস্তবায়ন?


JSON, এক্সএমএল এবং বিভিন্ন অন্যান্য ফরম্যাটের মতো, একটি ট্রি-ভিত্তিক সিরিয়ালাইজেশন ফর্ম্যাট। যদি আপনার বস্তুর বৃত্তাকার রেফারেন্স থাকে তবে এটি আপনাকে ভালবাসবে না, যেমন "গাছ" হবে:

root B => child A => parent B => child A => parent B => ...

একটি নির্দিষ্ট পথ বরাবর ন্যাভিগেশন নিষ্ক্রিয় করার উপায় প্রায়ই আছে; উদাহরণস্বরূপ, XmlSerializer আপনি মূল বৈশিষ্ট্যটিকে XmlIgnore হিসাবে চিহ্নিত করতে পারেন। জেসন সিরিয়ালাইজারের সাথে এটি সম্ভব কিনা তা আমি জানি না, DatabaseColumn যথাযথ মার্কার আছে কিনা ( খুব সম্ভবত, এটি প্রতিটি সিরিয়ালাইজেশান API উল্লেখ করার প্রয়োজন হবে)


Newtonsoft.Json ব্যবহার করে: আপনার Global.asax অ্যাপ্লিকেশন_Start পদ্ধতিতে এই লাইন যোগ করুন:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

আপনি সূত্র রেফারেন্স কারণ যে বৈশিষ্ট্য লক্ষ্য করতে পারেন। তারপর আপনি কিছু ভালো করতে পারেন:

private Object DeCircular(Object object)
{
   // Set properties that cause the circular reference to null

   return object
}

আমি ফিক্স ব্যবহার করছি, কারণ MVC5 দর্শনে নকআউট ব্যবহার করা।

কর্ম উপর

return Json(ModelHelper.GetJsonModel<Core_User>(viewModel));

ক্রিয়া

   public static TEntity GetJsonModel<TEntity>(TEntity Entity) where TEntity : class
    {
        TEntity Entity_ = Activator.CreateInstance(typeof(TEntity)) as TEntity;
        foreach (var item in Entity.GetType().GetProperties())
        {
            if (item.PropertyType.ToString().IndexOf("Generic.ICollection") == -1 && item.PropertyType.ToString().IndexOf("SaymenCore.DAL.") == -1)
                item.SetValue(Entity_, Entity.GetPropValue(item.Name));
        }
        return Entity_;  
    }

এটি DBContext T4 টেমপ্লেটটির কারণ যা EntityFramework সংস্থানগুলি তৈরি করার জন্য ব্যবহৃত হয়। পরিবর্তন ট্র্যাকিং সঞ্চালন করতে সক্ষম হবার জন্য, এই টেমপ্লেটগুলি আপনার সাথে আপনার চমৎকার POCO মোড়ানো দ্বারা প্রক্সি প্যাটার্ন ব্যবহার করে। এই তারপর জাভাস্ক্রিপ্ট Serializer সঙ্গে serializing যখন সমস্যা কারণ।

সুতরাং তারপর 2 সমাধান হয়:

  1. হয় আপনি শুধু serialize এবং ক্লায়েন্ট আপনার প্রয়োজন সম্পত্তি ফেরত
  2. আপনি প্রসঙ্গের কনফিগারেশনে এটি সেট করে স্বয়ংক্রিয় প্রক্সিগুলির প্রজন্ম বন্ধ করতে পারেন

    প্রসঙ্গ। কনফিগারেশন। ProxyyCreationEnabled = মিথ্যা;

নীচের নিবন্ধে খুব ভাল ব্যাখ্যা।

http://juristr.com/blog/2011/08/javascriptserializer-circular-reference/


জটিল বস্তুগুলি যা ফলে জেসন বস্তুটি ব্যর্থ হয় তা আসলেই ঘটে। এবং এটি ব্যর্থ হয় কারণ বস্তুর মানচিত্রটি যখন এটি শিশুদের ম্যাপ করে, যা তাদের পিতামাতাকে মানচিত্র করে, একটি বৃত্তাকার রেফারেন্স তৈরি করে। জসন এটি সিরিয়ালাইজ করার অসীম সময় নেবে, তাই এটি ব্যতিক্রমটির সাথে সমস্যাটিকে আটকায়।

এন্টিটি ফ্রেমওয়ার্ক ম্যাপিং একই আচরণ তৈরি করে, এবং সমাধানটি সমস্ত অবাঞ্ছিত বৈশিষ্ট্যগুলিকে বাতিল করতে হয়।

শুধু চূড়ান্ত উত্তর expliciting, পুরো কোড হবে:

public JsonResult getJson()
{
    DataContext db = new DataContext ();

    return this.Json(
           new {
                Result = (from obj in db.Things select new {Id = obj.Id, Name = obj.Name})
               }
           , JsonRequestBehavior.AllowGet
           );
}

যদি আপনি Result ভিতরে থাকা বস্তুগুলি চান না তবে এটি নিম্নোক্ত হতে পারে:

public JsonResult getJson()
{
    DataContext db = new DataContext ();

    return this.Json(
           (from obj in db.Things select new {Id = obj.Id, Name = obj.Name})
           , JsonRequestBehavior.AllowGet
           );
}

প্রদত্ত উত্তর ভাল, কিন্তু আমি মনে করি তারা একটি "স্থাপত্য" দৃষ্টিকোণ যোগ করে উন্নত করা যেতে পারে।

তদন্ত

MVC's Controller.Json ফাংশন কাজ করছে, কিন্তু এই ক্ষেত্রে একটি প্রাসঙ্গিক ত্রুটি প্রদান এ খুব খারাপ। Newtonsoft.Json.JsonConvert.SerializeObject ব্যবহার করে, ত্রুটি বৃত্তাকার রেফারেন্স ট্রিগার করা হয় যে সম্পত্তি ঠিক কি নির্দিষ্ট করে। আরো জটিল বস্তু অনুক্রমগুলি serializing যখন এটি বিশেষভাবে দরকারী।

সঠিক স্থাপত্য

কোনও ডাটা মডেলের সিরিয়ালাইজ করার চেষ্টা করা উচিত না (যেমন EF মডেল), যেমন সিরিয়ালাইজেশনের সময় ORM এর ন্যাভিগেশন বৈশিষ্ট্যগুলি বিধ্বংসী রাস্তা। তথ্য প্রবাহ নিম্নলিখিত হতে হবে:

Database -> data models -> service models -> JSON string 

স্বয়ংক্রিয় মডেলগুলি ব্যবহার করে ডেটা মডেলগুলি থেকে পরিষেবা মডেলগুলি পাওয়া যেতে পারে (যেমন Automapper )। এটি বৃত্তাকার রেফারেন্সগুলির অভাবের নিশ্চয়তা দেয় না, তবে সঠিক ডিজাইনটি করা উচিত: পরিষেবা মডেলগুলি অবশ্যই পরিষেবা গ্রাহকের (যা বৈশিষ্ট্যগুলি) প্রয়োজন তা অবশ্যই থাকা উচিত।

সেই বিরল ক্ষেত্রে, যখন ক্লায়েন্ট একই স্তরের একই স্তরের টাইপের সাথে একটি স্তরবিন্যাসের অনুরোধ করে, তখন সেটি প্যারেন্ট-> শিশু সম্পর্কের সাথে একটি রৈখিক গঠন তৈরি করতে পারে (কেবল শনাক্তকারীর ব্যবহার করে, রেফারেন্স নয়)।

আধুনিক অ্যাপ্লিকেশনগুলি একযোগে জটিল তথ্য কাঠামো লোড করা থেকে বিরত থাকে এবং পরিষেবা মডেলগুলি পাতলা হওয়া উচিত। উদাহরণ:

  1. একটি ইভেন্ট অ্যাক্সেস - শুধুমাত্র শিরোনাম ডেটা (সনাক্তকারী, নাম, তারিখ ইত্যাদি) লোড করা হয় -> পরিষেবা মডেল (JSON) শুধুমাত্র শিরোনাম ডেটা ধারণ করে
  2. পরিচালিত অংশগ্রহণকারীদের তালিকা - একটি পপআপ এবং অলস লোড তালিকাটি অ্যাক্সেস করুন -> পরিষেবা মডেল (JSON) শুধুমাত্র অংশগ্রহণকারীদের তালিকা ধারণ করে

মনে হচ্ছে আপনার অবজেক্টের সীমাবদ্ধ রেফারেন্সগুলি JSON সিরিয়ালাইজার দ্বারা সমর্থিত নয়। আপনি সব কলাম প্রয়োজন? ভিউতে আপনার প্রয়োজনীয় বৈশিষ্ট্যগুলি আপনি নিতে পারেন:

return Json(new 
{  
    PropertyINeed1 = data.PropertyINeed1,
    PropertyINeed2 = data.PropertyINeed2
});

এটি আপনার JSON অবজেক্টটিকে লাইটার এবং বুঝতে সহজ করবে। আপনার যদি অনেক বৈশিষ্ট্য থাকে তবে AutoMapper automatically ডিটিও বস্তুর এবং মানচিত্রগুলি দেখতে মানচিত্রে ব্যবহার করতে পারে।


using Newtonsoft.Json; একই সমস্যা ছিল এবং সমাধান হয়েছিল using Newtonsoft.Json;

var list = JsonConvert.SerializeObject(model,
    Formatting.None,
    new JsonSerializerSettings() {
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});

return Content(list, "application/json");

//first: Create a class as your view model

public class EventViewModel 
{
 public int Id{get;set}
 public string Property1{get;set;}
 public string Property2{get;set;}
}
//then from your method
[HttpGet]
public async Task<ActionResult> GetEvent()
{
 var events = await db.Event.Find(x => x.ID != 0);
 List<EventViewModel> model = events.Select(event => new EventViewModel(){
 Id = event.Id,
 Property1 = event.Property1,
 Property1 = event.Property2
}).ToList();
 return Json(new{ data = model }, JsonRequestBehavior.AllowGet);
}




subsonic