作者: 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. elementui分页点击详情返回分页样式

    updated(){ $(".el-pager").children("li").removeClass("active"); var li ...

  2. NLR:利用非线性回归,梯度下降法求出学习参数θ,进而求得Cost函数最优值——Jason niu

    import numpy as np import random def genData(numPoints,bias,variance): x = np.zeros(shape=(numPoints ...

  3. 【python】web开发

    No1: hello.py def application(environ,start_response): start_response('200 OK',[('Content-Type','tex ...

  4. Qt创建任务栏进度条

    一.正文 任务栏进度条是Windows7就引入的一种UI形式,通常用于显示软件当前正在执行的任务的进度(如编译程序的进度.下载任务的进度).如下: 在Qt中使用任务栏进度条也是非常容易的一件事情.Qt ...

  5. 在cikuapi.com上抓取相关词

    最近用到文本相关性计算,要在开放域语料上操作,找了好久没找到好的方法,后来看到了清华的梁斌老师建的cikuapi,上面能查询一些相关词,自己写代码爬的时候出现中文解码问题,遂到Github上找了下相关 ...

  6. 在UnrealEngine中用Custom节点实现径向模糊

    //input NotUse 为了开启SceneTextureLookup函数而连接的节点,但是不参与逻辑 //input UV 屏幕缓存的坐标坐标 //input Strength 力度 //inp ...

  7. BZOJ.1178.[APIO2009]会议中心(贪心 倍增)

    BZOJ 洛谷 \(Description\) 给定\(n\)个区间\([L_i,R_i]\),要选出尽量多的区间,并满足它们互不相交.求最多能选出多少个的区间以及字典序最小的方案. \(n\leq2 ...

  8. Python3之弹性力学——应力张量1

    题目 已知某点的应力张量为: \[ \left[ \begin{array}{ccc} \sigma_{x} &\tau_{xy} &\tau_{xz}\\ \tau_{yx} &am ...

  9. JavaScript基础笔记(二)变量、作用域和内存问题

    变量.作用域和内存问题 一.基本类型和引用类型的值 基本类型值:简单的数据段 引用类型值:由多个值构成的对象 基本类型是按值访问的,引用类型是按引用访问的. 不能给基本类型的值添加属性,尽管不会报错. ...

  10. 反射与内置方法str del

    1.反射 用字符串来操作类或者对象的属性 class People:# country= 'china'# def __init__(self,name):# self.name= name## de ...