如何在CLR过程中使用Json Parser?

Par*_*rsa 5 c# sql-server serialization json sqlclr

我正在疯狂尝试在我的类库中使用Json序列化器/反序列化器并在SQL Server中导入我的程序集。

我正在使用响应Json字符串的WebAPI,并且我想创建调用该API并使用api结果的CLR Sql Procedure。

我尝试了两种方法来反序列化Json字符串:

1)System.Web.Script.Serialization

2)System.Runtime.Serialization.Json

第一个让我看到这个错误:

程序集'system.web.extensions,版本= 4.0.0.0,区域性=中性,publickeytoken = 31bf3856ad364e35。” 在SQL目录中找不到。(Microsoft SQL Server,错误:6503)

第二个:

程序集'system.runtime.serialization,版本= 4.0.0.0,文化=中性,publickeytoken = b77a5c561934e089。' 在SQL目录中找不到。(Microsoft SQL Server,错误:6503)

错误画面截图

有什么方法可以解析我的类库中的json吗?(除了在类库中为我自己创建一个Json Serializer / Deserializer之外!)

Visual Studio 2015社区,Microsoft Sql Server 2016开发人员

先感谢您。

Sol*_*zky 6

不幸的是,没有任何方法既是 .NET Framework(即内置)的一部分又是 SAFE.

如果您想要一个内置方法,那么您可以尝试使用DataContractJsonSerializer类,它位于System.Runtime.Serialization.Json命名空间中,而该命名空间又位于System.Runtime.Serialization.dll 中。您可以在此处找到使用它的示例:如何:序列化和反序列化 JSON 数据但是,为了在 SQL Server 内部使用它,您需要导入System.Runtime.Serialization.dll,因为它不是受支持的 .NET Framework 库之一。因为它不受支持,这意味着三件事:

  1. 您需要将包含程序集的数据库设置为TRUSTWORTHY ON(由于需要PERMISSION_SETUNSAFE),通常建议不要这样做,因为它存在安全风险。

  2. 您不能确定底层代码没有做可能导致“奇怪”行为的事情,例如缓存静态类变量中的值。SQLCLR 为每个程序集所有者 + 数据库组合使用一个应用程序域。因此,该类将在执行该代码的所有会话之间共享。

  3. 您不能保证System.Runtime.Serialization.dll(或其两个依赖库之一:System.ServiceModel.InternalsSMDiagnostics)在未来的 .NET Framework 更新中不会更改为混合模式 DLL。SQL Server 中只允许使用纯 MSIL 库,因此如果这 3 个库中的任何一个更改为“混合”,那么您在 SQL Server 中的代码将开始失败并且无法修复它;你将不得不重新编码。这之前发生过:System.ServiceModel 随着 .NET 4.0 的发布成为混合模式,因此使用它的代码可以在 SQL Server 2005、2008 和 2008 R2(全部链接到 CLR v 2.0 和框架版本 2.0 - 3.5)中工作,但从SQL Server 2012(全部链接到 CLR v 4.0 和框架版本 4.0 及更高版本)。

但是,如果您想尝试,请执行以下操作(它会自动加载 2 个依赖的 DLL):

USE [someDB];

ALTER DATABASE CURRENT SET TRUSTWORTHY ON;

CREATE ASSEMBLY [System.Runtime.Serialization]
FROM 'C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll'
WITH PERMISSION_SET = UNSAFE;
Run Code Online (Sandbox Code Playgroud)

或者,您可以在项目中包含用于解析 JSON 的代码。您在这里也有一些选择:

  1. 虽然“首选”JSON 解析器是 Json.NET,但我无法将其作为SAFE程序集加载。自从我尝试以来已经有几年了,但是它有相当多的静态类变量用于缓存值(有助于性能,但在共享环境中不起作用),我似乎记得它依赖于一些不受支持的库(例如System.Runtime.Serialization)。

  2. 我使用JsonFx取得了一些成功。该代码还需要一些更新来处理静态类变量,但这是可能的。这个项目可以处理从 JSON 到几个不同标记的转换。

  3. 正如@EvaldasBuinauskas 的回答中所述,您可以尝试LitJSON项目。我还没有尝试过这个项目,所以不确定它的效果如何。它似乎比 JsonFX 项目小一点(不做其他格式),但截至目前,它有 25 个未解决的问题,而 JsonFX 只有 16 个。

    您可能应该查看两个项目的“问题”列表,以确保没有报告的内容会导致您出错。

  • 我也使用了 JsonFx,虽然我想将 JsonFx 添加到 sqlserver 程序集,但它给了我这个错误:<<< CREATE ASSEMBLY 失败,因为安全程序集“JsonFx”中的类型“XmlInTransformer”有一个静态字段“DefaultObjectName”。安全程序集中的静态字段的属性在 Visual C# 中必须标记为 readonly,在 Visual Basic 中必须标记为 ReadOnly,或在 Visual C++ 和中间语言中标记为 initonly。>>>之后我转到 JsonFx 源并将该属性设为只读!!!它有效,是真的吗??? (3认同)
  • 你提供的代码有效,非常感谢你,但它有警告说:如果你升级或维护这个程序集或 .NET Framework,你的 CLR 集成例程可能会停止工作。你的建议是什么?在您的项目中包含用于解析 JSON 的代码?还是继续导入 System.Runtime.Serialization ? (2认同)
  • 我认为让它们只读,也许将来它会抛出意想不到的错误...... (2认同)