作者: 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. JAVA首次课堂测试总结

    暑期生活已经结束,新的学期也已经开始,而暑期放假之前约定的JAVA首次课堂测试也如期的到来,本次测试真的可以学到和多东西,也有很多感想. 首先体会最深的就是系主任所说的软件工程不是那么好学的,真的需要 ...

  2. Java内存管理-掌握类加载器的核心源码和设计模式(六)

    勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇文章介绍了类加载器分类以及类加载器的双亲委派模型,让我们能够从整体上对类加载器有 ...

  3. config-toolkit之config-face

    config-toolkit是当当网开发的开源项目,使用起来非常的方便.对于很多配置都可以写在配置中心中,进行配置数据的获取,这样我们可以不用把很多信息写在了代码里面,例如数据库账号密码等信息. co ...

  4. java date HHmmss hhmmss

    系统交互时,用到时间流水号的设计,出现时间流水号相同的情况,故对时间格式化各种情况做了研究 SimpleDateFormat(format) format:年月日  yyyyMMdd时分秒  HHmm ...

  5. ORM(二)

    一.ORM简介         对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.简单的说,ORM是通过使 ...

  6. MVC面试问题与答案

    读这篇文章不意味着你一定要去并且能搞定MVC面试.这篇文章的目的是在面试之前让你快速复习MVC知识.这篇文章也不是MVC培训课程. 如果你想学习MVC,从这儿开始 Learn MVC ( Model ...

  7. [iOS]视图与UIVIew

     1.UIView以及各控件间的关系: 2.视图的层次结构 一般来说一个应用中只有一个UIWindow.

  8. Charles——前端必备模拟后端数据

    Charles--前端必备模拟后端数据 现在都是前后端分离开发了,前端开发者经常会遇到一个问题如何模拟后端数据来进行开发调试,在这里给大家介绍一个前端神器--Charles. 安装 安装就不赘述了,直 ...

  9. mybatis查询到count(*)返回值

    resultType="int" <select id="num_List_" parameterType=" xxx" result ...

  10. innerHTML innerText与outerHTML间的区别

    innerHTML与innerText及outerHTML间的区别最容易使初学者搞混淆,为了更好的使读者区分开.下面我就通过一个demo来解释: 代码: <!DOCTYPE html>&l ...