У меня немного уникальная проблема. Я регистрирую dll как сборку внутри базы данных SQL Server, которая принимает переменную SQLXml вместе с двумя строками и сериализует данные в формате JSON.
Для справки, вот вызов метода:
[SqlProcedure]
public static void Receipt(SqlString initiatorPassword,
SqlString initiatorId,
SqlXml XMLOut,
out SqlString strMessge)
Я бы использовал Newtonsoft.Json или Jayrock для этого приложения, если бы это было приложение любого другого типа.Обычно я следую приведенному здесь ответу и делаю что-то похожее на:
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, но если я правильно понимаю этот блог, это вызвано тем, что правила SqlCLR не разрешают .Load() и унаследованные методы без подписи и наличия сильное имя. У моей DLL и сторонних 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 ( )
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. Мой цикл — это попытка динамического программирования, так как для создания этого XML извлекается около 200 полей.
Примечание. Я использую Jayrock и работаю в .Net Framework 2.0. В настоящее время я не могу изменить версию фреймворка.