类型为"类型"的成员的WCF异常

时间:2014-05-09 04:15:20

标签: c# wcf serialization

我试图在方法中传递MyData的对象(实际引用)但是获得异常。通道类型是NetTcpBinding。

  

System.ServiceModel.CommunicationException:尝试序列化参数http://tempuri.org/:myData时出错。 InnerException消息是' Type' System.RuntimeType'使用数据合同名称'运行时类型:http://schemas.datacontract.org/2004/07/System'不是预期的。考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。'。有关更多详细信息,请参阅InnerException。 ---> System.Runtime.Serialization.SerializationException:键入' System.RuntimeType'使用数据合同名称'运行时类型:http://schemas.datacontract.org/2004/07/System'不是预期的。考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。

[DataContract]
[KnownType(typeof(System.Type))] //Keeping it here or removing does not make any difference
public class MyData
{
    private Type m_MyType = typeof(string);
    [DataMember]
    public Type MyType //WCF does not like this. If removed of data type changed then ok 
    {
        get { return m_MyType; }
        set { m_MyType = value; }
    } 

    private Int32 m_Member1 = 0;
    [DataMember]
    public Int32 Member1
    {
        get { return m_Member1; }
        set { m_Member1 = value; }
    }
}

2 个答案:

答案 0 :(得分:4)

This是您不应该从WCF操作返回Type的一个原因。

我建议你返回Type.AssemblyFullyQualifiedName而不是Type。然后在呼叫端你可以:

var type = Type.GetType(returnedTypeName);

如果您想使用Type来创建新对象等。

答案 1 :(得分:0)

一个解决方案,即使它可能不是最好的(这个解决方案更通用,可以允许你使用任何二进制可序列化对象),可以手动序列化你的类,通过WCF发送一个byte []和在接收时反序列化:

    public static byte[] Serialize(Object _obj)
    {
        if (_obj == null)
            return null;

        byte[] Result = null;

        BinaryFormatter bf = new BinaryFormatter();
        using (MemoryStream memStream = new MemoryStream())
        {
            bf.Serialize(memStream, _obj);
            Result = memStream.ToArray();
        }

        return Result;
    }

这里是反序列化:

    public static Object Deserialize(byte[] _arrBytes)
    {
        Object obj = null;
        using (MemoryStream memStream = new MemoryStream())
        {
            BinaryFormatter binForm = new BinaryFormatter();
            memStream.Write(_arrBytes, 0, _arrBytes.Length);
            memStream.Seek(0, SeekOrigin.Begin);

            lock (assemblyResolveLocker)
            {
                assemblyCmpt = 0;
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

                obj = (Object)binForm.Deserialize(memStream);

                AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            }

        }

        return obj;
    }

这是我用来手动为dll解决自定义类型问题的程序集解析器(你可以猜到,DllPaths是一个包含我可能必须使用的dll路径的列表):

    private static object assemblyResolveLocker = new object();
    private static int assemblyCmpt = 0;

    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        if (assemblyCmpt < Conf.DllPaths.Count)
        {
            try
            {
                int c = 0;
                foreach (string _path in Conf.DllPaths)
                {
                    if (c < assemblyCmpt)
                    {
                        c++;
                    }
                    else
                    {
                        //Load my Assembly 
                        Assembly assem = Assembly.LoadFile(_path);
                        if (assem != null)
                            return assem;
                    }
                }

            }
            catch { ;}

            return Assembly.GetExecutingAssembly();
        }
        else
        {
            return Assembly.GetExecutingAssembly();
        }
    }

我希望它可以提供帮助!