مرجع تخصصی برنامه نویسان

بزرگترین انجمن برنامه نویسان فارسی زبان

خطا در هنگام ساخت WeBApi و استفاده از EF CodeFirst

ﺳﻪ شنبه, 29 آبان 1397 10:37

خطا در هنگام ساخت WeBApi و استفاده از EF CodeFirst

سلام . 

پروژه ای دارم که از طریق WebApi  درون Asp MVC میخوام اطلاعات بانکم رو که به روش EF CodeFirst  ایجاد کردم رو نمایش بده .  

مدل رو درون یک کلاس لایبرری تحت عنوان Datalayer به پروژم اضافه کردم که .درون پوشه مدل سه تا کلاس دارم (Pages,PageGroups,PageComments) . (جداول باهم ارتباط یک به چند دارند .)

    public  class Page
    {
        [Key]
        public int PageID { get; set; }


        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        [Display(Name = "شماره گروه")]
        public int GroupID { get; set; }


        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        [Display(Name = "عنوان گروه")]
        public string Title { get; set; }


        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        [Display(Name = "توضیحات")]
        public string ShowDescription { get; set; }


        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        [Display(Name = "متن")]
        public string Text { get; set; }



        [Display(Name = "تعداد بازدید")]
        public int Visit { get; set; }



        [Display(Name = "تصویر")]
        public string ImageName { get; set; }



        [Display(Name = "نمایش درون اسلایدر")]
        public bool ShowInSlider { get; set; }



        [Display(Name = "وضعیت")]
        public bool IsActive { get; set; }



        public virtual PageGroup PageGroup { get; set; }
        public virtual ICollection<PageComment> PageComment { get; set; }


        public Page()
        {
           
           

        }

    }
   public  class PageComment
    {


        [Key]
        [Display(Name = "شناسه نظر")]
        public int CommentID { get; set; }


        [Display(Name = "شماره صفحه")]
        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        public int PageID { get; set; }


        [Display(Name = "نام")]
        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        public string Name { get; set; }


        [Display(Name = "ایمیل")]
        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        public string Email { get; set; }



        [Display(Name = "وبسایت")]
        public string WebSite { get; set; }


        [Display(Name = "نطر")]
        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        public string Comment { get; set; }


        [Display(Name = "تاریخ ثبت نظر")]

        public DateTime CreateDate { get; set; }


        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        [Display(Name = "وضعیت")]
        public bool IsActive { get; set; }





        public virtual Page Page { get; set; }

        public PageComment()
        {

        }
    }
    public  class PageGroup
    {

        [Display(Name = "شماره گروه")]
        [Key]
        public int GroupID { get; set; }


        [Required(ErrorMessage = "لطفا {0} را وارد کنید ")]
        [Display(Name = "عنوان گروه")]
        public string GroupTitle { get; set; }





        public virtual ICollection<Page> Page { get; set; }


        public PageGroup()
        {
            this.Page = new HashSet<Page>();
        }

        
    }

از طریق یک اینترفیس قرارداد هام رو ذکر کردم و درون پوشه سرویس ریپوزیتوری خودم رو که شامل عملیات CRUD هست پیاده سازی کردم 

 public class PageGroupRepository : IPageGroupRepository
    {

        NewsSampleContext db = new NewsSampleContext();

        IEnumerable<PageGroup> IPageGroupRepository.GetAllGroups()
        {
            return db.PageGroup;
        }

        PageGroup IPageGroupRepository.GetGroupByID(int groupId)
        {
            return db.PageGroup.Find(groupId);
        }

        bool IPageGroupRepository.InsertGroup(PageGroup pageGroup)
        {
            try
            {
                 db.PageGroup.Add(pageGroup);
                return true;

            }
            catch (Exception)
            {

                return false;
            }
        }

        bool IPageGroupRepository.UpdateGroup(PageGroup pageGroup)
        {
            try
            {
                db.Entry(pageGroup).State = System.Data.Entity.EntityState.Modified;
                return true;
            }
            catch (Exception)
            {

                return false;
            }
        }

        bool IPageGroupRepository.DeleteGroup(PageGroup pageGroup)
        {
            try
            {
                db.Entry(pageGroup).State = System.Data.Entity.EntityState.Deleted;
                return true;
            }
            catch (Exception)
            {

                return false;
            }
        }

        bool IPageGroupRepository.DeleteGroupByID(int groupId)
        {
            try
            {
                var q = db.PageGroup.Find(groupId);
                db.Entry(q).State = EntityState.Deleted;
                return true;
            }
            catch (Exception e)
            {
                return false;
            }

        }


        void IPageGroupRepository.save()
        {
            db.SaveChanges();
        }


    }

و در انتها میخوام که اطلاعاتم رو درون کنترلر api ام از ریپوزیتوری دریافت کنم و در مرورگر که به صورت Json نمایش میده مشاهده کنم 

   public class NewsApiController : ApiController
    {
        //NewsSampleContext db=new NewsSampleContext();
        static  readonly  IPageGroupRepository rep=new PageGroupRepository();

        public IEnumerable<PageGroup> GetAllGroups()
        {
            return rep.GetAllGroups().AsEnumerable();


        }

    }

ولی با پیغام خطای روبرو مواجه میشم . خیلی جستجو کردم و هر نوع تنظیماتی که درون فایل های Global.asax و WebApiConfig رو که هم عنوان شده انجام دادم اما بازم همینه.

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Data.Entity.DynamicProxies.PageGroup_E59D67A0F1338A7B9C5635D970D09B9D36AACB457B1777A17AFD1382BFB586FB' with data contract name 'PageGroup_E59D67A0F1338A7B9C5635D970D09B9D36AACB457B1777A17AFD1382BFB586FB:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.SerializationException
</ExceptionType>
<StackTrace>
at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiType(XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDeclaredType, Boolean writeXsiType, Int32 declaredTypeID, RuntimeTypeHandle declaredTypeHandle) at WriteArrayOfPageGroupToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , CollectionDataContract ) at System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, Boolean verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator writer, Object graph, DataContractResolver dataContractResolver) at System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter writer, Object graph) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content) at System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()
</StackTrace>
</InnerException>
</Error>

پی نوشت : در اخر برای تست یک کلاس (table ) به پروژم اضافه کردم تحت عنوان Product که هیچ ارتباطی با جداول دگم نداره .و اطلاعاتی رو درونش پر کردم . اطلاعات این جدول رو نمایش میده . متوجه شدم که از ارتباطات جداولم هست که اون پیغام خطارو بهم میده . باید چیکار کنم اگه بخوام از همون جداولم اطلاعات رو واکشی کنم ؟

ﺳﻪ شنبه, 29 آبان 1397 12:02

نیاز است متد ToList را در کنترلر فراخوانی کنید:

return rep.GetAllGroups().ToList()  

کسانی که از این پست تشکر کرده اند : pourya.montakhab,
ﺳﻪ شنبه, 29 آبان 1397 15:16

جواب نمیده دوست عزیز .

چهارشنبه, 30 آبان 1397 09:28

اگر امکانش هست سورس کدتون رو توی گیت هاب قرار بدید تا من بررسیش کنم.

کسانی که از این پست تشکر کرده اند : pourya.montakhab,
شنبه, 03 آذر 1397 13:30
شنبه, 03 آذر 1397 16:46

کد شما را اجرا کردم بدون مشکل بود تونستم Response دریافت کنم.

یکشنبه, 04 آذر 1397 00:18

فکر کنم شما از متد GetAllProduct اجرا گرفتین . اون مشکلی نداره . اجرا میشه . چون همونجا مقدار دهی کردم و با هیچ تیبل دگ ای در ارتباط نیست . مشکل اونجاییه که من میخوام از تیبل هایی که با هم ریلیشن دارند اجرا بگیرم . 

اگه ممکنه از متد GetAllPC اجرا بگبربن . (مربوط به  تیبل PageComment )

api/GetAllPC

یکشنبه, 04 آذر 1397 11:46

تمامی آنها به درستی کار میکنند:

یکشنبه, 04 آذر 1397 17:59
پس مشکل چی میتونه باشه ؟؟ کد که درسته .
یکشنبه, 04 آذر 1397 20:06

ممنونم جناب علیزاده عزیز مشکلم حل شد 

باید در سازنده DBContext پروژه LazyLoading رو غیرفعال میکردم . 

 public NewsSampleApiContext() : base("name=NewsSampleApiContext")
        {
            this.Configuration.LazyLoadingEnabled = false;
            this.Configuration.ProxyCreationEnabled = false;
        }

ارسال پاسخ برای این تاپیک

ارسال پاسخ مخصوص اعضا سایت می باشد ! میتوانید با حساب کاربری خود وارد سایت شده یا ثبت نام کنید