Вставка значений из массива в сообщение SOAP на основе ключа
В an ASP.NET приложение, в котором пользователи ("пользователь а") могут устанавливать свои собственные подключения к веб-сервисам с помощью SOAP, я позволяю им вставлять свой собственный конверт, который, например, может быть чем-то вроде:
//Formatted for Clarity
string soapMessage =
"<soap: Envelope //StandardStuff>
<soap:Header //StandardStuff>
<wsse:UsernameToken>
<wsse: Username>{F1}</wsse:Username>
<wsse: Password Type''>{F2}</wsse:Password>
</wsse:UsernameToken>
</soap:Header>
<soap:Body>
<ref:GetStuff>
<ref:IsActive>{F3}</ref:IsActive>
</ref:GetStuff>
</soap:Body>
</soap:Envelope>"
В то же время я "пользователь B", который отправляет массив данных, передаваемых из Javascript в виде json, который выглядит примерно так:
[
{
key: "F1",
value: "A"
},
{
key: "F2",
value: "B"
},
{
key: "F3",
value: "C"
}
];
Этот массив входит в fray в виде строки перед десериализацией (dynamic JsonObject = JsonConvert.DeserializeObject(stringifiedJson);
).
Теперь я хотел бы быть возможность вставлять соответствующие значения в конверт, желательно с такой степенью безопасности, которая не позволит людям делать странные вещи, вставляя странные значения в массив (регулярное выражение, вероятно, будет моим последним средством).
До сих пор я знаю о концепции построения строки так (с заменой {}
в сообщении soap на {0}, {1} & {2}
):
string value1 = "A";
string value2 = "B";
string value3 = "C";
var body = string.Format(@soapMessage, value1, value2, value3);
request.ContentType = "application/soap+xml; charset=utf-8";
request.ContentLength = body.Length;
request.Accept = "text/xml";
request.GetRequestStream().Write(Encoding.UTF8.GetBytes(body), 0, body.Length);
Но количество значений в этом массиве, а также может меняться в зависимости от ввода пользователя, а также порядка сдвига ссылок, так что мне нужно что-то более гибкое. Я очень новичок в том, чтобы делать звонки с мылом,так что как можно более глупый ответ будет оценен.
3 ответа:
Подумайте о создании функции, которая заменила бы заполнители соответствующими значениями.
private string FormatMessage(string soapMessage, IDictionary<string, string> parameters) { var message = soapMessage; foreach (var kvp in parameters) { var placeholder = "{" + kvp.Key + "}"; if (message.IndexOf(placeholder) > -1) { message = message.Replace(placeholder, kvp.Value); } } return message; }
Где словарь был извлечен из JSON, предоставленного функции.
var parameters = JsonConvert.DeserializeObject<IDictionary<string, string>>(json); string body = FormatMessage(soapMessage, parameters);
Однако вам потребуется проверить предоставленные значения и ключи, чтобы избежать инъекций, которые могут негативно повлиять на вашу систему.
Всегда полезно обрабатывать xml с помощью xml-процессоров вместо замены строк. Моя идея перекрестного мышления, возможно, не совсем подходит для вашего использования, я не получил вашу общую картину на 100% , я должен признать.
В любом случае мой ответ заключается в том, что вы можете использовать XPath в качестве ключа, который позволит вам использовать инструменты обработки xml на бэкэнде. Вам не обязательно проверять что-либо на этом этапе, это очень зависит от архитектуры.
Итак, по моему мнению, javascript обеспечивает эту структуру:
[ { key: "//family-name", value: "Michael" }, { key: "//nickname", value: "Jackson" } ];
И бэкэнд:
XmlElement foo = (XmlElement)doc.SelectSingleNode(key); foo.InnerText = value;
Лучший инструмент для этой работы, ИМХО, это XSLT:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:crs="CRS610MI" exclude-result-prefixes="crs"> <xsl:output method="xml"/> <xsl:template match="/"> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <soap:Body> <xsl:apply-templates select="node()|@*"/> </soap:Body> </soap:Envelope> </xsl:template> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
Есть пост на SO, касающийся этой конкретной темы:
Оберните XML в конверт SOAP в .net
.NET поддерживает XSLT из коробки, поэтому вам не понадобятся сторонние библиотеки. Я бы загрузил JSON в объект XML и применил его к шаблону XSLT, который вы измените, чтобы уважать вашу структуру XML в памяти.
Используйте XmlLoader в C# для загрузки JSON в XML объект:
XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); string jsonText = JsonConvert.SerializeXmlNode(doc); // To convert JSON text contained in string json into an XML node XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
Загрузка шаблона XSLT в .NET довольно проста:
Это чистый и профессиональный подход, который, я считаю, соответствует вашим критериям.var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader( Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));