1

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

尝试序列化参数http://tempuri.org/:GetUserResult时出错。InnerException 消息是 'Type 'RoleProxy' with data contract name 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;
    }
}

这是我正在调用的函数:

[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);

    ...

}

服务器正确接收了结果,但是我找不到一些序列化问题。有什么解决办法吗?

谢谢。

4

1 回答 1

2

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

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

作为一个额外的观察,这也意味着你Equals的代码是错误的:

    if (obj.GetType() != typeof(Role)) return false;
    return Equals((Role)obj);

应该:

    return Equals(obj as Role);

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

于 2012-09-19T09:16:06.960 回答