作者: 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 特性。发现能正常运行了。

四、心得

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

  1. 对于 .NET Framework 已有但 .NET Core/Standard 没有的功能。可尝试搜索NuGet包,很多功能其实已经有官方包了。
  2. 安全透明类(或结构)里面不能引用SecurityCritical(安全关键)的特性。需给类(或结构)加上 SecuritySafeCriticalAttribute 特性。
  3. 使用NuGet包时容易遇到SecurityCritical(安全关键)的类,即使是官方的包也有时会有这种情况,故需注意加上 SecuritySafeCriticalAttribute 特性。

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

参考文献

[C#] .NET Core/Standard 1.X 项目中如何使用XmlIgnoreAttribute等标准范围外的内容,兼谈如何解决“violation of security transparency rules failed”(违反安全透明规则失败)异常的更多相关文章

  1. 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想试试,我 ...

  2. .NET Standard SDK 样式项目中的目标框架

    系列目录     [已更新最新开发文章,点击查看详细] 包表示形式 .NET Standard 引用程序集的主要分发载体是 NuGet 包. 实现会以适用于每个 .NET 实现的各种方式提供. NuG ...

  3. 在ASP.NET Core 2.0 web项目中使用EntityFrameworkCore

    一.安装EFCode包 EFCore需要根据不同的数据库选择不同的数据库提供程序database provider,各数据库的包地址:https://docs.microsoft.com/zh-cn/ ...

  4. 在项目中,多个方法会调用相同的sql语句,怎么解决各个方法的不同sql查询,解决冲突。

    公司的代码中sql语句,可能会被多个方法进行调用,但是有的方法会关联到别的表,这样的话,如果修改不当,那么同样调用该sql语句的方法,会出现报错. 最近做的公司的一个功能,就出现这样一个问题,虽然本功 ...

  5. [bug] Authentication failed for token submission (认证失败)异常

    原因 gitee上下的项目,启动后能访问首页,但登录报错.原因是根据用户名上数据库查密码没有得到结果,中间任何环节有问题都可能导致,我的是因为mapper.xml中的<mapper namesp ...

  6. 将 Net 项目升级 Core项目经验:(二)修复迁移后Net Standard项目中的错误

    修复迁移后Net Standard项目中的错误 接上一章,项目编译结果如下: 解决依赖dll引用 在Net Framework项目的引用如下: 各引用和作用: log4net(1.10.0.0) 用于 ...

  7. 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 ...

  8. .NET Core 3.0或3.1 类库项目中引用 Microsoft.AspNetCore.App

    本文为原创文章.首发:http://www.zyiz.net/ 在 ASP.NET Core 3.0+ web 项目中已经不需要在 .csproj 中添加对 Microsoft.AspNetCore. ...

  9. [C#] .NET Core/Standard 2.0 编译时报“CS0579: Duplicate 'AssemblyFileVersionAttribute' attribute”错误的解决办法

    作者: zyl910 一.缘由 当创建 .NET Core/Standard 2.0项目时,VS不会像.NET Framework项目一样自动生成AssemblyInfo.cs文件. 而且,若是手工在 ...

随机推荐

  1. gradle3.0新命令

    摘抄原文https://mp.weixin.qq.com/s/6UZhaI9cILJiPGYHkXd73g No1: Implementation compile 指令被标注为过时方法,而新增了两个依 ...

  2. Django之认证系统

    Django之认证系统 cookie和session 1.cookie不属于http协议范围,由于http协议无法保持状态,但实际情况,我们却又需要“保持状态”,因此cookie就是在这样一个场景下诞 ...

  3. P2347 砝码称重-DP方案数-bitset

    P2347 砝码称重 DP做法 : 转化为 01背包. 进行方案数 更新.最后统计种类. #include<bits/stdc++.h> using namespace std; #def ...

  4. Jenkins部署码云SpringBoot项目

    本文介绍jenkins如何从gitee上clone项目,然后使用maven打包并后台启动. 1.Jenkins介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续 ...

  5. c++ STL 数据结构底层结构

    + STL 的实现: 1.vector 底层数据结构为数组 ,支持快速随机访问 2.list 底层数据结构为双向链表,支持快速增删 3.deque 底层数据结构为一个中央控制器和多个缓冲区,详细见ST ...

  6. [算法]Collebarative Filtering

    挖坑 https://en.wikipedia.org/wiki/Collaborative_filtering

  7. Codeforces.618F.Double Knapsack(构造 鸽巢原理)

    题目链接 \(Description\) 给定两个大小为\(n\)的可重集合\(A,B\),集合中的元素都在\([1,n]\)内.你需要从这两个集合中各选一个非空子集,使它们的和相等.输出方案. \( ...

  8. RabbitMQ主题模式

    Send类 package topics; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; imp ...

  9. 如何使用TDD和React Testing Library构建健壮的React应用程序

    如何使用TDD和React Testing Library构建健壮的React应用程序 当我开始学习React时,我努力的一件事就是以一种既有用又直观的方式来测试我的web应用程序. 每次我想测试它时 ...

  10. CCNA