【问题标题】:WCF Exception on Member of type "Type"类型为“类型”的成员的 WCF 异常
【发布时间】:2014-06-26 17:09:59
【问题描述】:

我正在尝试在方法中传递 MyData 的对象(实际上是引用),但出现异常。通道类型为 NetTcpBinding。

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

【问题讨论】:

    标签: c# wcf serialization


    【解决方案1】:

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

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

    var type = Type.GetType(returnedTypeName);
    

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

    【讨论】:

    • 帖子中解释的观点是有道理的。但这种行为并不受欢迎。
    【解决方案2】:

    一个解决方案,即使它可能不是最好的(这个解决方案更通用,可以允许您使用任何二进制可序列化对象),可能是手动序列化您的类,通过 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();
            }
        }
    

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 2012-08-11
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 2013-11-12
      相关资源
      最近更新 更多