首页 文章

“类型”类型成员的WCF异常

提问于
浏览
0

我试图在方法中传递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; }
    }
}

2 回答

  • 4

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

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

    var type = Type.GetType(returnedTypeName);
    

    如果要使用Type创建新对象等 .

  • 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();
            }
        }
    

    我希望它可以帮助你!

相关问题