1

我有一个返回 System.Version 的 WCF 操作 MyGetVersion()。在调试从 Silverlight 服务引用对其的调用时,我验证了该服务是否返回了正确的 System.Version 对象。在服务参考中,自动生成的方法:

       public System.Version EndMyGetVersion(System.IAsyncResult result) {
            object[] _args = new object[0];
            System.Version _result = ((System.Version)(base.EndInvoke("MyGetVersion", _args, result)));
            return _result;
        }

引发异常:

尝试通过方法'DynamicClass.ReadVersionFromXml(System.Runtime.Serialization.XmlReaderDelegator, System.Runtime.Serialization.XmlObjectSerializerReadContext, System.Xml.XmlDictionaryString[], System.Xml.XmlDictionaryString[])' 访问方法'System.Version.. ctor()' 失败。

我必须打开“CLR 异常中断”助手才能看到这一点。否则,它是一个 TargetInvocationException。据我所知, System.Version() 构造函数是公开的。我究竟做错了什么?

4

1 回答 1

1

问题是 System.Version 的构造函数在 .NET Framework 中是公共的,但它不在 Silverlight 中(根据 Reflector,它是内部的)。因此,虽然该类型在完整框架中是可序列化的,但它不在 Silverlight 中,并且添加服务引用工具应该已将其替换为 SL 中的等效类型 - 这是工具中的一个错误(我将向产品团队报告,感谢您找到它)。

作为变通方法,我建议对 Version 使用“代理”类型,并在您的服务合同中仅将其用于数据传输:

[DataContract]
public class VersionDTO
{
    [DataMember]
    public int Major { get; set; }
    [DataMember]
    public int Minor { get; set; }
    [DataMember]
    public int Build { get; set; }
    [DataMember]
    public int Revision { get; set; }

    public VersionDTO(Version version) {
        this.Major = version.Major;
        this.Minor = version.Minor;
        this.Build = version.Build;
        this.Revision = version.Revision;
    }
}

[ServiceContract]
public interface ITest
{
    [OperationContract]
    VersionDTO GetVersion();
}

考虑到您在评论中提到的问题,另一种选择是将生成的 Silverlight 代理中对 Version 类的引用替换为与其等效的类。下面的类可用于从 .NET 反序列化 SL 中的 Version 对象。

    [DataContract(Name = "Version", Namespace = "http://schemas.datacontract.org/2004/07/System")]
    public class SLVersion
    {
        [DataMember(Order = 1, Name = "_Build")]
        public int Build { get; set; }
        [DataMember(Order = 2, Name = "_Major")]
        public int Major { get; set; }
        [DataMember(Order = 3, Name = "_Minor")]
        public int Minor { get; set; }
        [DataMember(Order = 4, Name = "_Revision")]
        public int Revision { get; set; }
    }
于 2011-07-20T20:27:32.957 回答