如何在C#中使用JavascriptSerializer序列化嵌套实体(模型)

本文关键字:嵌套 序列化 实体 模型 JavascriptSerializer | 更新日期: 2024-09-26 01:57:31

我正在构建一个ASP.NET Web应用程序,同时也在使用实体框架代码优先。在这种情况下,我使用两个实体(客户和联系人),它们之间有一对多关系(一个客户可以有多个联系人)。从数据库中获取数据时,一切都很顺利。我也使用Viewmodel,所以在我的数据实体旁边,我还有两个模型,分别称为CustomerModel和ContactModel。

下面我将展示我的实体和视图模型:

客户实体

[Table("Customer")]
    public class Customer
    {
        [Key()]
        public Guid Id { get; set; }
        //other non-relevant properties
        public virtual List<Contact> Contacts { get; set; }
    }

联系实体

[Table("Contact")]
    public class Contact
    {
        [Key()]
        public Guid Id { get; set; }
        //non-relevant properties
        [ForeignKey("Customer")]
        public Guid CustomerId { get; set; }
        [Required]
        public virtual Customer Customer { get; set; }
    }

客户型号

[Serializable]
    public class CustomerModel
    {
        public Guid Id { get; set; }
        //non-relevant properties
        [ScriptIgnore(ApplyToOverrides = true)]
        public virtual List<ContactModel> Contacts { get; set; }
    }

ContactModel

[Serializable]
    public class ContactModel
    {
        public Guid Id { get; set; }
        //non-relevant properties
        public Guid CustomerId { get; set; }
        [ScriptIgnore(ApplyToOverrides = true)]
        public virtual CustomerModel Customer { get; set; }
    }

当我运行我的应用程序和代码时,它在后端运行良好,直到它需要在我的HomeController中将其序列化为JSON。

public ActionResult GetCustomerById(Guid id)
        {
            CustomerModel customer = new CustomerManager().GetById(id);
            string output = serializer.Serialize(customer);
            return Content(output);
        }

即使是CustomerModel对象也会获得2个联系人,但在我的Serialize(customer)方法中,它不会将其解析为JSON。所以实际上,当我调试它并查看我的输出时,我看到了每个属性,但没有看到嵌套的ContactModels。

在我的情况下,string output不包含两个Contacts。我该如何解决此问题?我也在Stackoverflow上检查了一些"类似"的问题,但没有结果。

如何在C#中使用JavascriptSerializer序列化嵌套实体(模型)

好吧,我看到你缺少了一个概念DTO和循环引用,简单地说,你必须为你想要交付的内容创建一个模型。让你头疼的是层次/引用,所以我去掉了我们模型中的所有漏洞。

想想a->b->a,它可能会导致json看起来像这个

{a: b{a:b}

这本质上就是你想要的。

public JsonResult GetCustomerById(Guid id)
{
    CustomerModel customer = new CustomerManager().GetById(id);
    CustomerResultModel output = new CustomerResultModel(){
        id = customer.Id,
        Contacts = GetContacts(customer.Contacts)
    };
    return Json(output, JsonRequestBehavior.AllowGet); 
    //If you only POST then remove the AllowGet (the action name says Get so I'm assuming
}
private IEnumerable<ContactResultModel> GetContacts(Contacts){
    foreach(var a in Contacts){
        //When you use the yield keyword in a statement, you indicate that the method, operator, or get accessor in which it appears is an iterator.
        yield return new ContactResultModel(){            
            Id  = a.Id,
            CustomerId = a.CustomerId
        };
    }
}

型号

class CustomerResultModel{
    public Guid id {get;set;}
    public IEnumerable<ContactResultModel> Contacts {get;set;}
}
class ContactResultModel{
    public Guid id {get;set;}
    public Guid CustomerId {get;set;}
}