我正在学习WCF,并尝试创建一个公开Project及其任务的小型服务(标准的Entity Framework hello world)。
类结构如下:
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public virtual ICollection<Task> Tasks { get; set; }
}
public class Task
{
public int TaskId { get; set; }
public string Title { get; set; }
public virtual Project RelatedProject { get; set; }
}
DB上下文出现在:
之后public class ProjectContext : DbContext
{
public DbSet<Project> Projects { get; set; }
public DbSet<Task> Tasks { get; set; }
}
最后,服务端点:
public IEnumerable<Project> getProjects()
{
ProjectContext p = new ProjectContext();
return p.Projects.AsEnumerable();
}
问题是这个模型会抛出一个System.ServiceModel.CommunicationException,但是,如果我从模型中删除虚拟属性,它会工作,但我会松开Project和Task之间的实体框架链接。
有类似设置的人吗?
答案 0 :(得分:2)
我用这个把头撞了几个小时。经过大量调试后,谷歌给出了答案,我觉得在这里发布是正确的,因为这是我在谷歌获得的第一个结果。
在[ServiceContract]
接口声明(通常为IProjectService.cs
public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
{
var dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
{
var dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void Validate(OperationDescription description)
{
// Do validation.
}
}
要求是
using System.ServiceModel.Description;
using System.Data.Objects;
using System.ServiceModel.Channels;
然后在[OperationContract]
关键字下添加[ApplyDataContractResolver]
关键字,您就可以了!
答案 1 :(得分:0)
要通过WCF发送数据,您应该禁用延迟加载(dataContext.ContextOptions.LazyLoadingEnabled = false;
)。
为了确保加载了您想要的数据,您需要使用预先加载(通过Include方法)。
您需要将功能更改为:
public IEnumerable<Project> getProjects()
{
ProjectContext p = new ProjectContext();
p.ContextOptions.LazyLoadingEnabled = false;
return p.Projects.Include("Tasks").AsEnumerable();
}