gpt4 book ai didi

c# - 每当将虚拟添加到属性时出现 SerializationException

转载 作者:行者123 更新时间:2023-11-30 14:28:08 26 4
gpt4 key购买 nike

我的 web api 项目中有一个 Report 类:

[KnownType(typeof(Employee))]
[DataContract]
public class Report
{
[DataMember]
public int Id { get; set; }

public string ManagerId { get; set; }
public string EmployeeId { get; set; }

[DataMember]
public virtual Employee Manager { get; set; }

[DataMember]
public virtual Employee Employee { get; set; }
}

如果 virtual 在方法签名中,我会得到以下异常:

Type 'System.Data.Entity.DynamicProxies.Report_1FFC700B8A805A61BF97A4B9A18D60F99AAA83EE08F4CA2E2454BADA9737B476' with data contract name 'Report_1FFC700B8A805A61BF97A4B9A18D60F99AAA83EE08F4CA2E2454BADA9737B476:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver 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 DataContractSerializer.

如果不是一切正常。我错过了什么?


编辑以包含对象检索代码

API Controller

[ResponseType(typeof(IEnumerable<Report>))]
public IHttpActionResult GetLogs([FromUri] string id)
{
return Ok(_loggingService.GetReportsByEmployeeId(id));
}

服务

public IQueryable<Report> GetReportsByEmployeeId(string employeeId)
{
return _reports.GetAll().Where(x => x.ManagerId.Equals(employeeId) || x.EmployeeId.Equals(employeeId));
}

存储库

public IQueryable<T> GetAll()
{
return _dbSet;
}

最佳答案

大概您正在使用 Entity Framework 或类似的 ORM 检索此对象。

当您没有任何虚拟属性时,ORM 可以安全地使用您的类型的实例。但是,当您拥有虚拟属性时,ORM 必须使用自己的类型来支持延迟加载,这就是为什么您看到序列化程序提示它无法序列化类型“DynamicProxies”的原因。

为避免这种情况,请将域模型与序列化模型分开,并在调用 Select 时返回序列化模型的一个实例。

或者,关闭 ORM 中的延迟加载(不推荐)

编辑:添加评论中讨论的示例

如前所述,您的域模型(您用来与数据库交互的数据的对象表示)和您的业务模型(您为业务逻辑操作的数据的对象表示)最好分开。此外,服务之外的任何东西都不应直接接触域模型,因为这样做有可能引发意外的延迟加载、代码库中的职责模糊或其他不良结果。

顺便说一句,这种分离将避免您遇到的问题。下面的示例当然可以根据需要随意更改 namespace 和类型名称。

商业模式

namespace MyCompany.MyProject.BusinessModels
{
[KnownType(typeof(Employee))]
[DataContract]
public class Report
{
[DataMember]
public int Id { get; set; }

[DataMember]
public virtual Employee Manager { get; set; }

[DataMember]
public virtual Employee Employee { get; set; }
}
}

领域模型

namespace MyCompany.MyProject.DomainModels
{
// this separation may seem like overkill, but when you come to
// want different business models than your domain models, or to decorate
// this model with Entity Framework specific attributes, you'll be glad
// for the separation.
public class Report
{
public int Id { get; set; }

public virtual Employee Manager { get; set; }

public virtual Employee Employee { get; set; }
}
}

服务

public IQueryable<BusinessModels.Report> GetReportsByEmployeeId(string employeeId)
{
return _reports // _reports is a collection of Type DomainModels.Report
.GetAll()
.Where(x =>
x.ManagerId.Equals(employeeId)
|| x.EmployeeId.Equals(employeeId))
.Select(s =>
new BusinessModels.Report
{
Id = s.Id,
Employee = s.Employee,
Manager = s.Manager
})
.ToList();
// We don't want database access happening outside of the service.
// ToList() executes the SQL *now* rather than waiting until
// the first time you enumerate the result.
}

关于c# - 每当将虚拟添加到属性时出现 SerializationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30379802/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com