سؤال

أواجه مشكلات مع المرجع الدائري عندما أحاول إجراء تسلسل لكائن تم إرجاعه عبر EF4 CTP5.أنا أستخدم النهج الأول للكود وpoco البسيط لنموذجي.

لقد أضفت سمات [ScriptIgnore] إلى أي خصائص توفر مراجع خلفية لكائن ما ويبدو أن كل شيء يعمل بشكل مزعج بشكل مزعج إذا قمت بإنشاء مثيل poco يدويًا، على سبيل المثال.يتم إجراء تسلسل إلى JSON بشكل جيد، ويتم الاعتراف بسمة scriptignore.ومع ذلك، عندما أحاول إجراء تسلسل لكائن تم إرجاعه من DAL، أحصل على استثناء المرجع الدائري "تم اكتشاف مرجع دائري أثناء تسلسل كائن من النوع 'System.Data.Entity.DynamicProxies.xxxx'"

لقد جربت عدة طرق لاسترداد البيانات ولكنها جميعًا واجهت هذا الخطأ:

    public JsonResult GetTimeSlot(int id) {
        TimeSlotDao tsDao = new TimeSlotDao();
        TimeSlot ts = tsDao.GetById(id);
        return Json(ts);
    }

تعمل الطريقة الموضحة أدناه بشكل أفضل قليلاً بدلاً من كائن الوكيل الديناميكي للفاصل الزمني الذي يسبب المرجع الدائري الخاص بكائن الموعد.

    public JsonResult GetTimeSlot(int id) {
        TimeSlotDao tsDao = new TimeSlotDao();
            var ts = from t in tsDao.GetQueryable()
                 where t.Id == id
                 select new {t.Id, t.StartTime, t.Available, t.Appointment};
        return Json(ts);
    }

هل من أفكار أو حلول لهذه المشكلة؟

تحديث أفضل استخدام برنامج التسلسل الجاهز إن أمكن على الرغم من أن Json.Net عبر nuget لا بأس به كبديل وآمل أن يكون من الممكن استخدامه كما كنت أنوي أيضًا ...

هل كانت مفيدة؟

المحلول

لقد واجهت مشكلة مماثلة مع خدمة WCF المستضافة ومحاولة تسلسل كائنات POCO مع فئة DataContractJsonserializer. لا يبدو أن المسلسل المدمج في JSON يتعامل مع المراجع الدائرية على الإطلاق. تمكنت من الالتفاف عليه من خلال التعامل مع التسلسل بنفسي باستخدام json.net المسلسل ، وعودة سلاسل JSON من أساليب بلدي. لدى json.net serializer خيار لتجاهل المراجع الدائرية لأن JSON نفسها لا تدعمها.

نصائح أخرى

بغض النظر عما فعلته، ظل الوكلاء الديناميكيون يمثلون نقطة شائكة، وذهبت إلى حد إزالة جميع المراجع الدائرية في النموذج الخاص بي!ولكن لا تزال المشكلة قائمة.

لقد قمت بتجربة Json.Net ولكن حدثت نفس المشكلة.

في النهاية عثرت على منشور حول استخدام JavaScriptConverter مخصص

http://hellowebapps.com/2010-09-26/producing-json-from-entity-framework-4-0-generated-classes/

نفذت الكود وعمل كل شيء على ما يرام

لقد حللت هذا دون الحاجة إلى اللجوء إلى مسلسل JSON خارجي. في مصور ، قمت بتعطيل الوكيل في مُنشئ سياق كائني.

لست متأكدًا لماذا يعمل هذا لكنني نشرت سؤال متابعة هنا.

لقد استخدمت متناقضًا التالي. لاحظ أنني ورثت من camelcaseContractPropertyResolver للحصول على هذه الميزة أيضًا ، ولكن يمكنك أيضًا أن ترث مباشرة من DefaultContractResolver.

using System;
using System.Collections.Generic;
using System.Reflection;
using Newtonsoft.Json.Serialization;

namespace MyNamespace
{
    /// <summary>
    /// This class enables EntityFramework POCO objects to be serialized. In some cases POCO
    /// objects are subclassed by a proxy which has an additional member _entityWrapper. This
    /// object prevents serialization (circular references and references to non-serializable types).
    /// This removes the _entityWrapper from the list of members to be serialized.
    /// </summary>
    public class ContractResolver : CamelCasePropertyNamesContractResolver
    {
        protected override List<MemberInfo> GetSerializableMembers(Type objectType)
        {
            if (objectType.FullName.StartsWith("System.Data.Entity.DynamicProxies."))
            {
                var members = base.GetSerializableMembers(objectType);
                members.RemoveAll(memberInfo => memberInfo.Name == "_entityWrapper");
                return members;
            }
            return base.GetSerializableMembers(objectType);
        }
    }
}

لاستخدامه ، قم بإنشاء المسلسل الخاص بك ثم اضبط خاصية ContractResolver على مثيل جديد لهذه الفئة:

var ser = JsonSerializer.Create(sJsonSerializerSettings);            
ser.ContractResolver = new ContractResolver(); 

لقد قابلت هذه القضية أيضًا. تحتوي الإجابات على هذا الموضوع على حلول الأرقام. لكن أفضل حلول مختلفة لحالات مختلفة مع شرح وأعدد من دون تسلسلات مخصصة وجدت في المقالة عن طريق هونغاي صن - معالجة مرجعية حلقة في واجهة برمجة تطبيقات الويب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top