2017-10-19 9 views
5

ユーザー(「ユーザー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」は、JSONとJavaScriptから受け継が同時に::、例えば、これらの線に沿って何かすることができ

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

この配列は、逆シリアル化される前に文字列として入ります(dynamic JsonObject = JsonConvert.DeserializeObject(stringifiedJson);)。

これで、対応する値をエンベロープに挿入することができます。おそらく、配列に奇妙な値を挿入することによって人々がファンキーなことをすることを許さない程度のセキュリティが確保されたいと思います。私の最後の手段)。

これまでのところ、私は({0}, {1} & {2}に置き換えられてSOAPメッセージに{}年代で)そうのような文字列を構築する概念を知ってる:

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呼び出しを行うのがとても新しいので、できるだけ愚かな答えが得られるでしょう。

+0

'nustache'(https://github.com/jdiamond/Nustache)や' handlebars.net'(https://github.com/rexm/Handlebars.Net)のような既存のテンプレートエンジンを評価しましたか? –

+0

私はこのプロジェクトに新しい図書館を追加する自由がないので、私はしていません。これらが必要でないようなオプションは、好みを持つでしょう。 – Patrick

答えて

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

システムに悪影響を及ぼす可能性のある注射を避けるために、値とキーの有効性を確認する必要があります。

+0

これらの値を検証する方法はありますか?問題は、あるユーザーが別のユーザーにメッセージを入力することに関係しているため、このメッセージまたは値に含まれる内容についての事前知識がないことです。 – Patrick

+0

@Patrick、これらは実装の問題で、メッセージを変換する前に処理する必要があります。また、コードを管理している場合は、メッセージを変換する前に、指定された値が現在のユーザーと一致しているかどうかを常に確認できます。 – Nkosi

1

文字列置換の代わりにxmlプロセッサを使用してxmlを処理することをお勧めします。 私のクロス思考のアイデアはあなたのユースケースにちょうど適合しないかもしれません、私はあなたの大きな写真を100%得ることができませんでした。

とにかく私の答えは、バックエンドでxml処理ツールを利用できるようにxpathsをキーとして使用できるということです。この時点で何かを検証する必要はありません。これはアーキテクチャに大きく依存しています。

だから私の心の中では、Javascriptを、この構造を提供します。

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

とバックエンド:

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

アイデアは、soap-messageがユーザAによって提供され、値がユーザBによって提供されるということです。そうすれば、ユーザAがXMLセレクタで思考するのが複雑になるかもしれませんが、私はあなたのアウト・オブ・ザ・イズ-boxアイデア – Patrick

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> 

このトピックに関するご意見はあります:

Wrap XML in SOAP envelope in .net

.NET XSLTをそのまま使用できるため、サードパーティのライブラリは不要です。JSONをXMLオブジェクトにロードし、それをXSLTテンプレートに適用します。このテンプレートは、メモリXML構造を尊重するように変更します。

は、XMLオブジェクトにあなたのJSONをロードするためにC#でXmlLoaderを使用してください:.NETでXSLTテンプレートをロード

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

が前方にかなりストレートです:

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

これは清潔で、プロであります私があなたの基準に合っていると信じているアプローチ。

関連する問題