如何在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上检查了一些"类似"的问题,但没有结果。
好吧,我看到你缺少了一个概念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;}
}