XML序列化期间缺少SecurityProtocolType.Ssl3枚举值

时间:2017-01-25 14:48:12

标签: c# .net enums xml-serialization sgen

我有以下简单的XML可序列化类型:

[XmlType]
public class TestType
{
    public System.Net.SecurityProtocolType ProtocolType { get; set; }
}

var instanceToSerialize = new TestType { ProtocolType = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 };

我可以在我的计算机和几台计算机上很好地序列化这个对象的实例。但是在我测试的其中一台计算机上,我遇到了以下异常:

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: Instance validation error: '4080' is not a valid value for System.Net.SecurityProtocolType.
at System.Xml.Serialization.XmlCustomFormatter.FromEnum(Int64 val, String[] vals, Int64[] ids, String typeName)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterTestType.Write1_SecurityProtocolType(SecurityProtocolType v)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterTestType.Write3_TestType(String n, String ns, TestType o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterTestType.Write4_TestType(Object o)

我比较了sgen.exe生成的工作和失败案例代码。在工作案例中,我生成了这段代码:

string Write1_SecurityProtocolType(global::System.Net.SecurityProtocolType v) {
    string s = null;
    switch (v) {
        case global::System.Net.SecurityProtocolType.@Ssl3: s = @"Ssl3"; break;
        case global::System.Net.SecurityProtocolType.@Tls: s = @"Tls"; break;
        case global::System.Net.SecurityProtocolType.@Tls11: s = @"Tls11"; break;
        case global::System.Net.SecurityProtocolType.@Tls12: s = @"Tls12"; break;
        default: s = FromEnum(((System.Int64)v), new string[] {@"Ssl3", 
            @"Tls", 
            @"Tls11", 
            @"Tls12"}, new System.Int64[] {(long)global::System.Net.SecurityProtocolType.@Ssl3, 
            (long)global::System.Net.SecurityProtocolType.@Tls, 
            (long)global::System.Net.SecurityProtocolType.@Tls11, 
            (long)global::System.Net.SecurityProtocolType.@Tls12}, @"System.Net.SecurityProtocolType"); break;
    }
    return s;
}

在失败的代码上,这是生成的代码:

string Write1_SecurityProtocolType(global::System.Net.SecurityProtocolType v) {
    string s = null;
    switch (v) {
        case global::System.Net.SecurityProtocolType.@Tls: s = @"Tls"; break;
        case global::System.Net.SecurityProtocolType.@Tls11: s = @"Tls11"; break;
        case global::System.Net.SecurityProtocolType.@Tls12: s = @"Tls12"; break;
        default: s = FromEnum(((System.Int64)v), new string[] {@"Tls", 
            @"Tls11", 
            @"Tls12"}, new System.Int64[] {(long)global::System.Net.SecurityProtocolType.@Tls, 
            (long)global::System.Net.SecurityProtocolType.@Tls11, 
            (long)global::System.Net.SecurityProtocolType.@Tls12}, @"System.Net.SecurityProtocolType"); break;
    }
    return s;
}

您可能会注意到{1}}枚举成员的代码未在失败的情况下生成。你知道为什么代码丢失了吗?

1 个答案:

答案 0 :(得分:3)

普通诊断是使用错误的引用程序集运行SGen.exe。 /reference命令行选项很重要,如果没有使用它然后它会回到c:\ windows \ microsoft.net

中的那些

鞋子适合,SecurityProtocolType枚举非常善变。它从.NET 4.0更改为4.5,添加了Tls11和Tls12枚举成员。这里有很多关于它的Q + A,即使在针对4.0的项目中也能启用它们。 SSLv3存在一个相当大的问题,它已被泄露beyond repair。因此,微软试图阻止程序员使用它,你可以在the .NETCore declaration中看到。 [Obsolete]属性是SGen.exe关注的属性。

对我来说,显而易见的是,可以使用什么样的参考组件。虽然SslProtocols.Ssl3在.NETCore中具有[Obsolete]属性,但SecurityProtocolType枚举成员does not。所以SGen.exe意外地使用.NETCore引用程序集并没有解释它。 Mono或Xamarin之类的东西并不容易解释。 Silverlight或PCL参考组件无法解释,至少在我的机器上没有。一个不稳定的测试版本总是有可能的。

除非您知道为SGen.exe使用异常/reference参数,否则最好的建议是在该计算机上重新安装.NET Framework。并且停止使用Ssl3,它确实已经过时了。