您好,欢迎来到爱玩科技网。
搜索
您的当前位置:首页[C#] .NET Core/Standard 1.X 项目中如何使用XmlIgnoreAttribute等标准范围外的内容,兼谈如何解决“violation of security transpar...

[C#] .NET Core/Standard 1.X 项目中如何使用XmlIgnoreAttribute等标准范围外的内容,兼谈如何解决“violation of security transpar...

来源:爱玩科技网

作者:

一、缘由

XML序列化是一个很常用的功能,但对于.NET Core/Standard,其直到2.0版才内置支持XML序列化。具体来说, .NET Core 2.0 或 .NET Standard 2.0 才有 类,而1.X版(.NET Core 1.0~1.1 或 .NET Standard 1.0~1.6)版没有。
这一点可以在官网的API参考页面()验证,若以 .NET Core/Standard 1.X版查看 类,会被回退到 .NET Framework 4.7。这就表示XML序列化功能是在.NET Core/Standard 1.X版标准范围外的。

可是XML序列化是很常用的功能,特别是XmlIgnoreAttribute很常用。有什么办法可以使 .NET Core/Standard 1.X 项目中 能使用它呢?

二、在 .NET Core 项目中使用NuGet的包,工作正常

查了一下,发现NuGet上有一个叫 的包。
把该包加入 .NET Core 项目,果然能正常使用XML序列化功能了。

三、在 .NET Standard 项目中使用NuGet的包,遇到“violation of security transparency rules failed”异常

3.1 问题

既然.NET Core项目能工作,那么应该也能用到.NET Standard项目中。
于是我尝试了一下,在.NET Standard类库项目中增加此NuGet包。编译成功了,随后在使用时发现问题——

  • 在.NET Framework项目引用它(.NET Standard类库项目)时,能正常工作。
  • 但在.NET Core项目引用它时,运行时却报告“violation of security transparency rules failed”(违反安全透明规则失败)异常。
Unhandled Exception: System.InvalidOperationException: There was an error reflecting type 'ZylLib.UnionTypes.UnionShort'. ---> System.MethodAccessException: Attempt to access method System.Xml.Serialization.XmlIgnoreAttribute..ctor() in violation of security transparency rules failed.
  at System.RuntimeMethodHandle.CheckLinktimeDemands(IRuntimeMethodInfo method, RuntimeModule module, Boolean isDecoratedTargetSecurityTransparent)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType, Boolean mustBeInheritable, IList derivedAttributes, Boolean isDecoratedTargetSecurityTransparent)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeFieldInfo field, RuntimeType caType)
  at System.Attribute.GetCustomAttributes(MemberInfo element, Boolean inherit)
  at System.Xml.Serialization.XmlAttributes..ctor(MemberInfo memberInfo)
  at System.Xml.Serialization.XmlReflectionImporter.GetAttributes(MemberInfo memberInfo)
  at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
  at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
  at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
  --- End of inner exception stack trace ---
  at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
  at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
  at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
  at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
  at ZylLib.UnionTypes.UnionTypesExample.TestShort(StringBuilder sb)
  at ZylLib.UnionTypes.UnionTypesExample.Output(StringBuilder sb)
  at ZylLib.UnionTypes.ConsoleExample.Program.Main(String[] args)

3.2 中途分析

调试时查了一下程序集的位置,发现所引用的是这个dll——

C:\Users\<用户名>\.nuget\packages\System.Xml.XmlSerializer\4.0.10\lib\DNXCore50\System.Xml.XmlSerializer.dll

看了一下,该程序集没有 AllowPartiallyTrustedCallers、SecurityTransparent 特性。导致所有代码默认是 SecurityCritical(安全关键)的,透明方法无法调用。

但这一点太奇怪了,.NET Core项目也用的是这个dll啊。.NET Core项目直接使用XML序列化是能正常工作的。表示.NET Core是 SecurityCritical(安全关键)的啊。
而且从异常来看,是Attribute.GetCustomAttributes这个底层方法报错的。
难道是“不能用NuGet包,只能用标准范围内”的吗?

3.3 最终解决

整理一下目前的调用关系——

  • XmlIgnoreAttribute 位于 NuGet包System.Xml.XmlSerializer。虽然MSDN上说该类是安全透明的,但NuGet包中的该类是 SecurityCritical(安全关键) 的。
  • .NET Standard项目中有一个 UnionShort 结构,它其中的字段用到了 XmlIgnoreAttribute。因本程序集配置了AllowPartiallyTrustedCallers,故该结构是安全透明的。
  • .NET Core 项目引用了 .NET Standard项目中的UnionShort结构,但根据该结构构造XmlSerializer时,底层的 CustomAttribute.GetCustomAttributes 抛“violation of security transparency rules failed”异常了。虽然.NET Core 项目是SecurityCritical的。

难道是安全透明类(或结构)里面不能引用SecurityCritical(安全关键)的特性?
编译时没报错啊,创建该类、调用方法也正常啊。现在只是在序列化时使用了该特性。

于是将 .NET Standard项目程序集的 AllowPartiallyTrustedCallers 特性去掉。发现能正常运行了。看来真的是“安全透明类(或结构)里面不能引用SecurityCritical(安全关键)的特性”。

去掉“AllowPartiallyTrustedCallers”不利于安全透明规则,于是将它恢复了。随后尝试给该结构体加上 SecuritySafeCriticalAttribute 特性。发现能正常运行了。

四、心得

经过这件事后,有了以下心得——

同理,遇到缺少 DataContractAttribute 特性时,可引用 NuGet上的 包。测试通过。

参考文献

  • MSDN《安全透明的代码,级别 2》.

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- aiwanbo.com 版权所有 赣ICP备2024042808号-3

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务