I´m getting an WCF Error on Serverside:
There was an error while trying to serialize parameter http://tempuri.org/:GetUserResult. The InnerException message was ‘Type ‘RoleProxy’ with data contract name RoleProxy:http://schemas.datacontract.org/2004/07/’ is not expected. …
My Problem is, that I dont have any RoleProxy Type, that could be serialized.
I have the following Class:
[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;
}
}
and here is the function i am calling:
[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);
...
}
The Result is received correctly by the server, but there is some serialitation problem which I coulndt find. Any solutions?
Thanks.
ORMs such as EF and NHibernate like to create proxy types at runtime that extend the default behaviour. Most regular code won’t care that it has a sub-type (Liskov substitution principle, etc) – but: inheritance aware serializers need to check what object they are actually working with.
Dealing with dynamic proxy types is a pain; some serializers can handle some proxies (i.e. by not treating the proxy as an unexpected sub-type, but instead serializing it as if it was the base type), but it is by no means universal. The most practical thing to do is to map your data back into a
Roleinstance, to make sure that what you give WCF is the object you told it about. AutoMapper might make a convenient implementation for such.As an additional observation, this also means that you
Equalscode is wrong:should be:
(noting that
Equals(Role)already handles thenullcase correctly for us)