将数组中的值插入基于密钥的SOAP消息中
在用户(“用户A”)可以使用SOAP设置自己的Web服务连接的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"
}
];
该数组在进行反序列化之前以字符串的形式输入(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);
但值的量以及可能根据用户的输入以及引用的转换顺序而改变,所以我需要更灵活的东西。我对SOAP调用非常陌生,所以尽可能愚蠢地回答,我们将不胜感激。
考虑创建一个函数,用它们各自的值替换占位符。
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%的我不得不承认。
无论如何,我的答案是,你可以使用xpaths作为关键,这将使你能够利用后端的XML处理工具。您现在不需要验证任何东西,这非常依赖于架构。
在我的脑海所以,JavaScript提供这样的结构:
[
{
key: "//family-name",
value: "Michael"
},
{
key: "//nickname",
value: "Jackson"
}
];
和后端:
XmlElement foo = (XmlElement)doc.SelectSingleNode(key);
foo.InnerText = value;
这个想法是soap消息是由用户A提供的,并且这些值是由用户B提供的,因此,让用户A在xml选择器中思考可能会很复杂,但我绝对喜欢你的out-of-the箱子的想法。 – Patrick
此作业的最佳工具,恕我直言,是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上有一篇文章:
Wrap XML in SOAP envelope in .net
.NET支持XSLT开箱即用,因此您不需要任何第三方库。我会将JSON加载到一个XML对象中,并将其应用于您将修改的XSLT模板,以尊重您在内存中的XML结构。
在C#中使用的XmlLoader到您的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);
加载.NET中的XSLT模板是非常简单的:
var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(
Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas()));
这是一个清洁和专业我认为符合您的标准。
您是否评估过任何现有模板引擎,如'nustache'(https://github.com/jdiamond/Nustache)或'handlebars.net'(https://github.com/rexm/Handlebars.Net)? –
我没有自由向这个项目添加新的库。在不需要这些选项的情况下,这样的选择会有偏好。 – Patrick