基于Key将数组中的值插入到SOAP消息中

时间:2017-10-19 14:47:50

标签: javascript c# asp.net web-services soap

在一个ASP.NET应用程序中,用户(“用户A”)可以使用SOAP建立自己的Web服务连接,我让他们插入自己的信封,例如,这些信封可能是这样的: / p>

//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);)之前作为字符串输入。

现在,我希望能够将相应的值插入到信封中,最好是具有一定程度的安全性,不允许人们通过在数组中插入奇怪的值来执行时髦的东西(正则表达式可能是我的不得已)。

到目前为止,我已经意识到构建字符串的概念(肥皂消息中的{}{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电话,所以尽可能地回答愚蠢的答案。

3 个答案:

答案 0 :(得分:1)

考虑创建一个用各自的值替换占位符的函数。

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);

但是,您需要验证提供的值和密钥,以避免可能对您的系统产生负面影响的注入。

答案 1 :(得分:1)

使用xml处理器而不是字符串替换处理xml始终是个好主意。 我的交叉思维可能并不完全适合你的用例,我不能100%得到你的全局照片我不得不承认。

无论如何,我的答案是你可以使用xpath作为密钥,这将使你能够在后端使用xml处理工具。此时您不必验证任何内容,这非常依赖于体系结构。

所以在我看来,javascript提供了这种结构:

[
  { 
    key: "//family-name", 
    value: "Michael" 
  },
  { 
    key: "//nickname", 
    value: "Jackson" 
  }
];

后端:

XmlElement foo = (XmlElement)doc.SelectSingleNode(key);
foo.InnerText = value;

答案 2 :(得分:0)

这项工作的最佳工具,恕我直言,是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()));

这是一种干净而专业的方法,我认为符合您的标准。