C# WCF参数序列化错误

C# WCF参数序列化错误,c#,wcf,serialization,C#,Wcf,Serialization,我在服务器端收到一个WCF错误: 尝试序列化参数时出错。InnerException消息为“Type”RoleProxy,数据协定名为RoleProxy:http://schemas.datacontract.org/2004/07/“这是不可能的 我的问题是,我没有任何可以序列化的RoleProxy类型 我有以下课程: [DataContract] [KnownType(typeof(Permission))] public class Role { protected virtual

我在服务器端收到一个WCF错误:

尝试序列化参数时出错。InnerException消息为“Type”RoleProxy,数据协定名为RoleProxy:http://schemas.datacontract.org/2004/07/“这是不可能的

我的问题是,我没有任何可以序列化的RoleProxy类型

我有以下课程:

[DataContract]
[KnownType(typeof(Permission))]
public class Role
{
    protected virtual long _ID { get; set; }

    [DataMember]
    public virtual long ID
    {
        get { return _ID; }
        // zum Test
        set { _ID = value; }
    }
    [DataMember]
    public virtual string Name { get; set; }
    [DataMember]
    public virtual bool IsDefault { get; set; }
    [DataMember]
    public virtual ICollection<Permission> Permissions { get; set; }

    public Role()
    {

    }

    public Role(string name, ICollection<Permission> permissions, bool isDefault = false)
    {
        Name = name;
        Permissions = permissions;
        IsDefault = isDefault;
    }

    public virtual bool HasPermission(Permission perm)
    {
        foreach(Permission permission in this.Permissions)
            if (permission.Equals(perm))
                return true;

        return false;
    }

    public virtual bool Equals(Role other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(other.Name, Name);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != typeof(Role)) return false;
        return Equals((Role)obj);
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }

    public override string ToString()
    {
        return Name;
    }
}
[DataContract]
[知识类型(类型(权限))]
公共阶级角色
{
受保护的虚拟长_ID{get;set;}
[数据成员]
公共虚拟长ID
{
获取{return\u ID;}
//zum试验
设置{u ID=value;}
}
[数据成员]
公共虚拟字符串名称{get;set;}
[数据成员]
公共虚拟bool IsDefault{get;set;}
[数据成员]
公共虚拟ICollection权限{get;set;}
公共角色()
{
}
公共角色(字符串名称、ICollection权限、bool isDefault=false)
{
名称=名称;
权限=权限;
IsDefault=IsDefault;
}
公共虚拟bool拥有权限(Permission perm)
{
foreach(此.Permissions中的权限)
if(permission.Equals(perm))
返回true;
返回false;
}
公共虚拟bool Equals(角色其他)
{
if(ReferenceEquals(null,other))返回false;
if(ReferenceEquals(this,other))返回true;
返回等于(other.Name,Name);
}
公共覆盖布尔等于(对象对象对象)
{
if(ReferenceEquals(null,obj))返回false;
if(ReferenceEquals(this,obj))返回true;
if(obj.GetType()!=typeof(Role))返回false;
返回等于((角色)obj);
}
公共覆盖int GetHashCode()
{
返回Name.GetHashCode();
}
公共重写字符串ToString()
{
返回名称;
}
}
下面是我调用的函数:

[ServiceContract]
[ServiceKnownType(typeof(Role))]
[ServiceKnownType(typeof(User))]
[ServiceKnownType(typeof(Permission))]
[ServiceKnownType(typeof(IList<Role>))]
[ServiceKnownType(typeof(IList<User>))]
[ServiceKnownType(typeof(IList<Permission>))]
public interface ISecurityManager
{
    ...

    [OperationContract]
    User GetUser(string userDomain, string userName);

    ...

}
[服务合同]
[ServiceKnownType(类型(角色))]
[ServiceKnownType(类型(用户))]
[ServiceKnownType(类型(权限))]
[ServiceKnownType(类型(IList))]
[ServiceKnownType(类型(IList))]
[ServiceKnownType(类型(IList))]
公共接口ISecurityManager
{
...
[经营合同]
用户GetUser(字符串userDomain,字符串userName);
...
}
服务器正确地接收到结果,但我发现有一些序列化问题。有什么解决办法吗


谢谢。

诸如EF和NHibernate之类的ORM喜欢在运行时创建扩展默认行为的代理类型。大多数常规代码并不关心它是否有子类型(Liskov替换原则等),但是:支持继承的序列化程序需要检查它们实际使用的对象

处理动态代理类型是一件痛苦的事情;某些序列化程序可以处理某些代理(即,不将代理视为意外的子类型,而是将其序列化为基本类型),但它决不是通用的。最实际的做法是将数据映射回
角色
实例,以确保所提供的WCF是您告诉它的对象。AutoMapper可能会为此类应用提供一个方便的实现

另外,这也意味着您的
等于
代码是错误的:

    if (obj.GetType() != typeof(Role)) return false;
    return Equals((Role)obj);
应该是:

    return Equals(obj as Role);

(注意,
Equals(Role)
已经为我们正确地处理了
null
案例)

您使用什么ORM来创建角色?您有使用automapper的示例吗?@user1663907用于该场景吗?只是
var fixed=Mapper.Map(角色)
,并将
固定的
交给WCFB,但我想返回一个用户而不是角色。角色只是用户的一个属性。。。我不明白重点。此外,您的代码无法工作,因为您需要提供一个目标映射类,如
var-mapping=Mapper.Map(role)
@用户1663907您显示的与
角色相关的代码
。可以随意更改映射,但是:对于映射
角色
,我发布的代码可以正常工作(我确实在本地验证了它,等等)。然而,只要您返回NHibernate代理,WCF就不会是您的朋友。经过进一步的研究,我发现了这个主题。有些人还建议设置lazy=false。。。我这么做了,结果成功了。它还节省了线路上的交通量:)