【发布时间】:2012-06-22 14:55:03
【问题描述】:
我有一个独特的问题。我正在将一个 dll 注册为 SQL Server 数据库中的一个程序集,该数据库接受一个 SQLXml 变量以及两个字符串,并将数据序列化为 JSON 格式。
作为参考,这里是方法调用:
[SqlProcedure]
public static void Receipt(SqlString initiatorPassword,
SqlString initiatorId,
SqlXml XMLOut,
out SqlString strMessge)
如果这是任何其他类型的应用程序,我会为此应用程序使用 Newtonsoft.Json 或 Jayrock。通常我会按照here 给出的答案做类似的事情:
XmlReader r = (XmlReader)XmlOut.CreateReader();
XmlDocument doc = new XmlDocument();
doc.load(r);
但是,由于我使用的是 SQLClr,因此有一定的规则。其中之一是 .Load() 和任何其他继承的方法都不能使用。我认为 .Net 框架说得最好:
System.InvalidOperationException:无法加载动态生成的序列化程序集。在某些托管环境中 装配负载功能受到限制, 考虑使用预生成的序列化程序。请参阅内部异常以获取更多信息。 ---> System.IO.FileLoadException:
LoadFrom()、LoadFile()、Load(byte[]) 和 LoadModule() 已被主机禁用。
我无论如何都不会流利地使用 SqlClr,但如果我正确理解 this blog,这是由于 SqlCLR 的规则不允许 .Load() 和继承的方法而没有签名并具有强名称。我的 DLL 和我正在使用的第 3 方 DLL 没有强名称,我也不能自己重建和签名它们。因此,这让我无法在不使用负载的情况下尝试完成此任务(除非有人知道另一种方法)
我唯一能想到的解决方案是一个非常丑陋的 while 循环,它不能正常工作,我得到了一个“Jayrock.Json.JsonException:JSON 对象内的 JSON 成员值必须在其成员之前名称”例外。这是我编写的 while 循环(我知道,这不是我最好的代码):
int lastdepth = -1;
Boolean objend = true;
Boolean wt = false;
//Write Member/Object statements for the header omitted
JsonWriter w = new JsonTextWriter()
while (m.Read())
{
if ((lastdepth == -1) && (m.IsStartElement()))
{//Checking for root element
lastdepth = 0;
}
if ((m.IsStartElement()) && (lastdepth != -1))
{//Checking for Start element ( <html> )
w.WriteMember(m.Name);
if (objend)
{ //Check if element is new Parent Node, if so, write start object
w.WriteStartObject();
objend = false;
}
}
if (m.NodeType == XmlNodeType.Text)
{ //Writes text here. NOTE: m.Depth > lastdepth here!!!!!!!
w.WriteString(m.Value);
wt = true;
}
if (m.NodeType == XmlNodeType.Whitespace) //If whitespace, keep on truckin
{ m.Skip(); }
if ((m.NodeType == XmlNodeType.EndElement) && (wt == false) && (lastdepth > m.Depth))
{//End element that ends a series of "Child" nodes
w.WriteEndObject();
objend = true;
}
if ((m.NodeType == XmlNodeType.EndElement) && (wt == true))//Standard end of an el
{ wt = false; }
lastdepth = m.Depth;
}
w.WriteEndObject();
jout = w.ToString();
}
我的问题是,由于我不能使用 .load() 并且我的 while 循环调试起来很麻烦,这里最好的方法是什么?通常讨论的另一种方法是反序列化为具有匹配变量的对象,但我有一个相当大的 XML 来自 SQL Server。我的循环是动态编程的一次尝试,因为有大约 200 个字段被拉出来制作这个 XML。
注意:我正在使用 Jayrock 并在 .Net Framework 2.0 中工作。我目前无法更改框架版本。
【问题讨论】:
-
AFAIK
XmlDocument.LoadXml()不需要领导动态程序集。您确定您没有尝试使用 XML 序列化吗?你能发布异常的堆栈跟踪吗?
标签: c# xml json .net-2.0 sqlclr