Передача параметров в виде Xml хранимой процедуре
у меня есть требование передать параметры в виде Xml в мои хранимые процедуры.
у меня есть служба WCF на среднем уровне, которая вызывает мой уровень данных, который, в свою очередь, перенаправляет запрос в соответствующую хранимую процедуру.
дизайн заключается в том, что служба WCF отвечает за построение Xml для передачи в репозиторий.
мне просто интересно, нужно ли контролировать, какие параметры содержатся в XML на среднем уровне или использовать словарь, созданный клиентом, который я затем конвертирую в Xml на среднем уровне?
на данный момент я пошел на последнее - например:
public TestQueryResponseMessage TestQuery(TestQueryRequestMessage message)
{
var result = Repository.ExecuteQuery("TestQuery", ParamsToXml(message.Body.Params));
return new TestQueryResponseMessage
{
Body = new TestQueryResponse
{
TopicItems = result;
}
}
}
private string ParamsToXml(Dictionary<string, string> nvc)
{
//TODO: Refactor
StringBuilder sb = new StringBuilder();
sb.Append("<params>");
foreach (KeyValuePair<string, string> param in nvc)
{
sb.Append("<param>");
sb.Append("<" + param.Key + ">");
sb.Append(param.Value);
sb.Append("</" + param.Key + ">");
sb.Append("</param>");
}
sb.Append("</params>");
return sb.ToString();
}
однако мне, возможно, придется сделать это первым способом. Е. Г.
public TestQueryResponseMessage TestQuery(TestQueryRequestMessage message)
{
string xml = string.Format("<params><TestParameter>{0}</TestParameter></params>",message.Body.TestParameter)
var result = Repository.ExecuteQuery("TestQuery", xml);
return new TestQueryResponseMessage
{
Body = new TestQueryResponse
{
TopicItems = result;
}
}
}
что рекомендует hivemind?
4 ответов
Если вы должны использовать xml; то вместо того, чтобы передавать словарь, я бы использовал класс, который представляет эти данные, и использовать XmlSerializer
чтобы получить его как xml:
[Serializable, XmlRoot("args")]
public class SomeArgs {
[XmlElement("foo")] public string Foo { get; set; }
[XmlAttribute("bar")] public int Bar { get; set; }
}
...
SomeArgs args = new SomeArgs { Foo = "abc", Bar = 123 };
XmlSerializer ser = new XmlSerializer(typeof(SomeArgs));
StringWriter sw = new StringWriter();
ser.Serialize(sw, args);
string xml = sw.ToString();
Это значительно упрощает управление аргументами, применяемыми к запросам, объектно-ориентированным способом. Это также означает, что вы не должны сделать свой собственный побег из XML...
Как только вы используете решение Боба уборщика, и у вас есть XML.
создайте хранимую процедуру с параметром XML. Затем в зависимости от того, сколько XML у вас есть и что вы с ним делаете, вы можете использовать Xquery или OpenXML для измельчения XML-документа. Извлеките данные и выполните правильное действие. Этот пример является базовым и псевдокодом, но вы должны понять идею.
CREATE PROCEDURE [usp_Customer_INS_By_XML]
@Customer_XML XML
AS
BEGIN
EXEC sp_xml_preparedocument @xmldoc OUTPUT, @Customer_XML
--OPEN XML example of inserting multiple customers into a Table.
INSERT INTO CUSTOMER
(
First_Name
Middle_Name
Last_Name
)
SELECT
First_Name
,Middle_Name
,Last_Name
FROM OPENXML (@xmldoc, '/ArrayOfCustomers[1]/Customer',2)
WITH(
First_Name VARCHAR(50)
,Middle_Name VARCHR(50)
,Last_Name VARCHAR(50)
)
EXEC sp_xml_removedocument @xmldoc
END
вы можете просто использовать класс сериализации объектов, как это
public class Serialization
{
/// <summary>
/// Serializes the object.
/// </summary>
/// <param name="myObject">My object.</param>
/// <returns></returns>
public static XmlDocument SerializeObject(Object myObject)
{
XmlDocument XmlObject = new XmlDocument();
String XmlizedString = string.Empty;
try
{
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(myObject.GetType());
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, myObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
}
catch (Exception e)
{
System.Console.WriteLine(e);
}
XmlObject.LoadXml(XmlizedString);
return XmlObject;
}
/// <summary>
/// Deserializes the object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="XmlizedString">The p xmlized string.</param>
/// <returns></returns>
public static T DeserializeObject<T>(String XmlizedString)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(XmlizedString));
//XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
Object myObject = xs.Deserialize(memoryStream);
return (T)myObject;
}
/// <summary>
/// To convert a Byte Array of Unicode values (UTF-8 encoded) to a complete String.
/// </summary>
/// <param name="characters">Unicode Byte Array to be converted to String</param>
/// <returns>String converted from Unicode Byte Array</returns>
private static String UTF8ByteArrayToString(Byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
String constructedString = encoding.GetString(characters);
return (constructedString);
}
/// <summary>
/// Converts the String to UTF8 Byte array and is used in De serialization
/// </summary>
/// <param name="pXmlString"></param>
/// <returns></returns>
private static Byte[] StringToUTF8ByteArray(String pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
}
тогда вам не нужно создавать XML вручную, плюс вы можете использовать это с любым элементом, чтобы преобразовать его с помощью XSLT
Я бы поместил код построения xml внутри объекта домена. Таким образом, вы можете просто позвонить obj.GetXML () из веб-службы или слоя данных.