【问题标题】:Silverlight ServiceReference causes MethodAccessExceptionSilverlight ServiceReference 导致 MethodAccessException
【发布时间】:2011-10-09 15:29:15
【问题描述】:

我有一个返回 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() 构造函数是公开的。我做错了什么?

【问题讨论】:

    标签: silverlight wcf service-reference


    【解决方案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; }
        }
    

    【讨论】:

    • 谢谢,很遗憾,该合同已被其他服务使用,其他客户需要 System.Version。我可能需要添加另一个操作,我猜它只是将它作为 Silverlight 客户端的字符串返回。
    • 您还可以更改为 SL 生成的代理,正如我在上面的答案中添加的那样。这种方法的唯一问题是,每当您从 Silverlight 更新服务引用时,您都必须再次替换该类。
    猜你喜欢
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 2015-08-11
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多