Silverlight ServiceReference导致MethodAccessException

时间:2011-07-20 18:25:57

标签: silverlight wcf service-reference

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

1 个答案:

答案 0 :(得分:1)

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

作为解决方法,我建议对版本使用“代理”类型,并在服务合同中仅将其用于数据传输:

[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; }
    }