0

WCFサービスの次のXML入力があります。XmlReaderを使用してメッセージを検証し、新しいメッセージに置き換えます。このプロセス中に、xml名前空間エイリアスはからに変更されxmlns:soapenvますxmlns:s

メッセージの再作成中に名前空間エイリアスを維持するには、次のC#コードでどのような変更を行う必要がありますか?

正しく置き換えられたメッセージコンテンツを表示するには、変更後に<s:Body>...ストリーム...</ s:Body>を表示するWCFメッセージ本文を参照してください。

WCF拡張性から–メッセージインスペクター

WCFメッセージオブジェクトは1回だけ「消費」できます。「消費」とは、読み取り、書き込み、またはコピーを意味します。メッセージ本文は基本的に1回限りのストリームであるため、一度消費されると、再度使用することはできません。したがって、インスペクターコードでメッセージを読み取る場合、WCFランタイムはそのメッセージをパイプラインの残りの部分で再利用できません(つまり、メッセージをエンコードして応答として送信したり、解析して操作したりすることはできません)。パラメーター)。したがって、インスペクターコードがメッセージを読み取る必要がある場合、メッセージを再作成するのはインスペクターの責任です。

入力

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header>
<To soapenv:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://local:54956/Service1.svc</To>
<Action soapenv:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/GetData</Action>
</soapenv:Header>
<soapenv:Body>
  <tem:GetData>
     <!--Optional:-->
     <tem:value>4</tem:value>
  </tem:GetData>
</soapenv:Body>
</soapenv:Envelope>

コード

 private void MyInspectorsValidateMessageBody(ref System.ServiceModel.Channels.Message message, bool isARequest)
    {

        string originalMessageText = message.ToString();

        if (!message.IsFault)
        {
            XmlDictionaryReaderQuotas quotas = new XmlDictionaryReaderQuotas();
            XmlReader bodyReader = message.GetReaderAtBodyContents().ReadSubtree();

            //Settings
            XmlReaderSettings wrapperSettings = new XmlReaderSettings();
            wrapperSettings.CloseInput = true;
            wrapperSettings.ValidationFlags = XmlSchemaValidationFlags.None;
            wrapperSettings.ValidationType = ValidationType.Schema;

            //Add a event handler for ValidationEventHandler of XmlReaderSettings
            //Validation happens while read of xml instance
            //wrapperSettings.ValidationEventHandler += new ValidationEventHandler(MyHandlerForXMLInspectionErrors);

            XmlReader wrappedReader = XmlReader.Create(bodyReader, wrapperSettings);

            this.isRequest = isARequest;

            MemoryStream memStream = new MemoryStream();
            XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateBinaryWriter(memStream);
            xdw.WriteNode(wrappedReader, false);
            xdw.Flush(); memStream.Position = 0;

            XmlDictionaryReader xdr = XmlDictionaryReader.CreateBinaryReader(memStream, quotas);

            //Reconstruct the message with the validated body
            Message replacedMessage = Message.CreateMessage(message.Version, null, xdr);
            replacedMessage.Headers.CopyHeadersFrom(message.Headers);
            replacedMessage.Properties.CopyProperties(message.Properties);
            message = replacedMessage;

            string replacedMessageText = replacedMessage.ToString();

        }
    }

出力

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://local:54956/Service1.svc</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IService1/GetData</Action>
</s:Header>
<s:Body>... stream ...</s:Body>
</s:Envelope>
4

1 に答える 1

2

いいえ、名前空間は変更されません。名前空間を参照するために使用されるプレフィックスを変更していますが、どちらの場合も名前空間自体は"http://schemas.xmlsoap.org/soap/envelope/"です。

元のドキュメントから:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                  xmlns:tem="http://tempuri.org/">

そして出力から:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

どのプレフィックスが使用されているかは気にする必要はありません。重要なのは実際の名前空間のURIです。

于 2013-03-25T16:39:01.170 に答える