[C#] .NET Core/Standard 1.X 项目中如何使用XmlIgnoreAttribute等标准范围外的内容,兼谈如何解决“violation of security transparency rules failed”(违反安全透明规则失败)异常
作者: zyl910
一、缘由
XML序列化是一个很常用的功能,但对于.NET Core/Standard,其直到2.0版才内置支持XML序列化。具体来说, .NET Core 2.0 或 .NET Standard 2.0 才有 XmlIgnoreAttribute类,而1.X版(.NET Core 1.0~1.1 或 .NET Standard 1.0~1.6)版没有。
这一点可以在官网的API参考页面(.NET API Browser)验证,若以 .NET Core/Standard 1.X版查看 XmlIgnoreAttribute 类,会被回退到 .NET Framework 4.7。这就表示XML序列化功能是在.NET Core/Standard 1.X版标准范围外的。
可是XML序列化是很常用的功能,特别是XmlIgnoreAttribute很常用。有什么办法可以使 .NET Core/Standard 1.X 项目中 能使用它呢?
二、在 .NET Core 项目中使用NuGet的包,工作正常
查了一下,发现NuGet上有一个叫 System.Xml.XmlSerializer 的包。
把该包加入 .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 特性。发现能正常运行了。
四、心得
经过这件事后,有了以下心得——
- 对于 .NET Framework 已有但 .NET Core/Standard 没有的功能。可尝试搜索NuGet包,很多功能其实已经有官方包了。
- 安全透明类(或结构)里面不能引用SecurityCritical(安全关键)的特性。需给类(或结构)加上 SecuritySafeCriticalAttribute 特性。
- 使用NuGet包时容易遇到SecurityCritical(安全关键)的类,即使是官方的包也有时会有这种情况,故需注意加上 SecuritySafeCriticalAttribute 特性。
同理,遇到缺少 DataContractAttribute 特性时,可引用 NuGet上的 System.Runtime.Serialization.Primitives 包。测试通过。
参考文献
- MSDN《安全透明的代码,级别 2》. https://msdn.microsoft.com/zh-cn/library/dd233102.aspx
- https://docs.microsoft.com/zh-cn/dotnet/api/?view=netstandard-1.0
- https://www.nuget.org/packages/System.Xml.XmlSerializer/4.0.11
- https://www.nuget.org/packages/System.Runtime.Serialization.Primitives/4.1.1
[C#] .NET Core/Standard 1.X 项目中如何使用XmlIgnoreAttribute等标准范围外的内容,兼谈如何解决“violation of security transparency rules failed”(违反安全透明规则失败)异常的更多相关文章
- ASP.NET CORE MVC 2.0 项目中引用第三方DLL报错的解决办法 - InvalidOperationException: Cannot find compilation library location for package
目前在学习ASP.NET CORE MVC中,今天看到微软在ASP.NET CORE MVC 2.0中又恢复了允许开发人员引用第三方DLL程序集的功能,感到甚是高兴!于是我急忙写了个Demo想试试,我 ...
- .NET Standard SDK 样式项目中的目标框架
系列目录 [已更新最新开发文章,点击查看详细] 包表示形式 .NET Standard 引用程序集的主要分发载体是 NuGet 包. 实现会以适用于每个 .NET 实现的各种方式提供. NuG ...
- 在ASP.NET Core 2.0 web项目中使用EntityFrameworkCore
一.安装EFCode包 EFCore需要根据不同的数据库选择不同的数据库提供程序database provider,各数据库的包地址:https://docs.microsoft.com/zh-cn/ ...
- 在项目中,多个方法会调用相同的sql语句,怎么解决各个方法的不同sql查询,解决冲突。
公司的代码中sql语句,可能会被多个方法进行调用,但是有的方法会关联到别的表,这样的话,如果修改不当,那么同样调用该sql语句的方法,会出现报错. 最近做的公司的一个功能,就出现这样一个问题,虽然本功 ...
- [bug] Authentication failed for token submission (认证失败)异常
原因 gitee上下的项目,启动后能访问首页,但登录报错.原因是根据用户名上数据库查密码没有得到结果,中间任何环节有问题都可能导致,我的是因为mapper.xml中的<mapper namesp ...
- 将 Net 项目升级 Core项目经验:(二)修复迁移后Net Standard项目中的错误
修复迁移后Net Standard项目中的错误 接上一章,项目编译结果如下: 解决依赖dll引用 在Net Framework项目的引用如下: 各引用和作用: log4net(1.10.0.0) 用于 ...
- Javaweb项目中出现java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone.异常
javaweb项目中java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represent ...
- .NET Core 3.0或3.1 类库项目中引用 Microsoft.AspNetCore.App
本文为原创文章.首发:http://www.zyiz.net/ 在 ASP.NET Core 3.0+ web 项目中已经不需要在 .csproj 中添加对 Microsoft.AspNetCore. ...
- [C#] .NET Core/Standard 2.0 编译时报“CS0579: Duplicate 'AssemblyFileVersionAttribute' attribute”错误的解决办法
作者: zyl910 一.缘由 当创建 .NET Core/Standard 2.0项目时,VS不会像.NET Framework项目一样自动生成AssemblyInfo.cs文件. 而且,若是手工在 ...
随机推荐
- 简单的使用Nginx框架搭建Web服务器~
系统环境Debian 8,内核版本 一.首先来安装nginx服务程序: 1.安装nginx服务需要的相关程序(记得在root权限下操作下面的指令) aptitude install libpcre3 ...
- python自带线程池
1. 注意: 导包是: from multiprocessing.pool import ThreadPool #线程池不在thrading中 2. 代码: from mutiprocessing.p ...
- jQuery获得页面绝对和相对的位置
获得某一元素绝对x,y位置,可以用offset方法 var X = $('#DivID').offset().top; var y=$("#divid").offset().lef ...
- Context家族
--摘自<android插件化开发指南> 1.ContextWrapper只是一个包装类,没有任何具体的实现,真正的逻辑都在ContextImpl里面 2.应用程序中包含多个Context ...
- 问题 L: An Invisible Hand - (2018年第二阶段个人训练赛第三场)
题目描述 There are N towns located in a line, conveniently numbered 1 through N. Takahashi the merchant ...
- Django2.0引入css、js、img文件
Django2.0引入css.js.img文件 一.文件结构 二.settings.py的配置 # Static files (CSS, JavaScript, Images) # https://d ...
- Shell学习之结合正则表达式与通配符的使用(五)
Shell学习之结合正则表达式与通配符的使用 目录 通配符 正则表达式与通配符 通配符 通配符的使用 正则表达式 正则表达式 正则表达式的使用 通配符 正则表达式与通配符 正则表达式用来在文件中匹配符 ...
- datatables数据渲染自定义
"data": "ip",渲染回调函数中的data['ip']字段将传给render函数中的data:render函数的返回内容将代替"data&qu ...
- 每天一条linux命令
1.ls ls -hG //MacOS下输出带颜色文件和目录 ls -a // 显示隐藏文件 ls -l // 显示文件权限和组信息 ls -lR /home //列出 home目录包括其内部子目录 ...
- Nodejs连接mysql的增、删、改、查操作
一,创建数据库 Source Database : my_news_test SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- ...