Insert values ​​from an array into a key-based SOAP message

In an ASP.NET application in which users ("User A") can configure their own connections to a web service using SOAP, I let them insert their own envelope, which, for example, could be something like these lines:

//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>" 

At the same time, I am “User B”, which sends an array of data passed from Javascript as json, which looks something like this:

 [ { key: "F1", value: "A" }, { key: "F2", value: "B" }, { key: "F3", value: "C" } ]; 

This array enters fray as a string before deserialization ( dynamic JsonObject = JsonConvert.DeserializeObject(stringifiedJson); ).

Now I would like to be able to insert the appropriate values ​​into the envelope, preferably with a degree of security that will prevent people from doing funky stuff by inserting strange values ​​into an array (regular expression will probably be my last resort).

Until now, I know the concept of constructing such a line (from {} in replacing a soap message with {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); 

But the number of values ​​in this array, as well as the value can vary depending on the user input, as well as the order of the offset of the links, so I need something more flexible. I am very new to making SOAP calls, so as deep as possible the answer will be appreciated.

+5
source share
3 answers

Consider creating a function that replaces placeholders with appropriate values.

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

If the dictionary was extracted from the JSON provided by the function.

 var parameters = JsonConvert.DeserializeObject<IDictionary<string, string>>(json); string body = FormatMessage(soapMessage, parameters); 

However, you will need to check the values ​​and keys provided to avoid injections that could adversely affect your system.

+1
source

It is always useful to process xml with xml processors instead of replacing a string. My idea of ​​cross-thinking may not suit your needs; I have not received your overall picture, which I must admit.

In any case, my answer is that you can use xpaths as a key that will allow you to use the xml processing tools on the backend. In this case, you do not have to check anything, it is very architecture dependent.

So, in my opinion, javascript provides this structure:

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

And the backend:

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

The best tool for this job, IMHO, is 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> 

This topic has a post:

Wrap XML in SOAP Envelope in .net

.NET Supports XSLT out of the box, so you don't need any third-party libraries. I would load JSON into an XML object and apply it to the XSLT template, which you will modify to respect your in-memory XML structure.

Use XmlLoader in C # to load JSON into an XML object:

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

Loading the XSLT template in .NET is pretty straight forward:

 var xml = XDocument.Load(JsonReaderWriterFactory.CreateJsonReader( Encoding.ASCII.GetBytes(jsonString), new XmlDictionaryReaderQuotas())); 

This is a clean and professional approach that, I believe, meets your criteria.

0
source

Source: https://habr.com/ru/post/1272750/


All Articles