Can XmlDictionaryReader process binary XML? If not, what to do?

I am trying to write a debugging tool that allows the user to view the new binary WCF XML format (application / soap + msbin1) as plain text. As soon as I found the XmlDictionaryReader class , I thought that everything would be done in a few minutes, but it did not work properly.

private string DecodeBinaryXML(byte[] binaryBuffer)
{
    if (binaryBuffer == null)
    {
        return "";
    }

    try
    {
        var doc = new XmlDocument();
        using (var binaryReader = XmlDictionaryReader.CreateBinaryReader(binaryBuffer, XmlDictionaryReaderQuotas.Max))
        {                    
            doc.Load(binaryReader);
            binaryReader.Close();
        }

        var textBuffer = new StringBuilder();
        var settings = new XmlWriterSettings()
        {
            // lots of code not relevant to the question
        };
        using (var writer = XmlWriter.Create(textBuffer, settings))
        {
            doc.Save(writer);
            writer.Close();
        }

        return textBuffer.ToString();
    }
    catch (Exception ex)
    {
        // just display errors in the text viewer
        return ex.ToString();
    }
}

Each "soap + msbin1" sample that I found online or generated myself throws a parsing exception in doc.Load () .

To find out what was going on, I created a simple test application and attacked the problem from a different direction.

// client
static void Main(string[] args)
{
    var binding = new CustomBinding(new TextMessageEncodingBindingElement(), 
                                    new HttpTransportBindingElement());            
    var proxy = ChannelFactory<IService1>.CreateChannel(binding, 
               new EndpointAddress("http://ipv4.fiddler:25381/Service1.svc"));
    Console.WriteLine(proxy.Echo("asdf"));
}

// shared interface
[ServiceContract()]
public interface IService1
{
    [OperationContract]
    string Echo(string input);
}

// server
public class Service1 : IService1
{
    public string Echo(string input)
    {
        return "WCF says hi to: " + input;
    }
}

The launch starts with an HTTP request that looks like this:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" 
            xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
     <a:Action s:mustUnderstand="1">http://tempuri.org/IService1/Echo</a:Action>
     <a:MessageID>urn:uuid:21a33e81-bfab-424f-a2e5-5116101a7319</a:MessageID>
     <a:ReplyTo>
        <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
     </a:ReplyTo>
     <a:To s:mustUnderstand="1">http://ipv4.fiddler:25381/Service1.svc</a:To>
  </s:Header>

  <s:Body>
      <Echo xmlns="http://tempuri.org/">
          <input>asdf</input>
      </Echo>
  </s:Body>
</s:Envelope>

XML . , XmlDictionaryWriter:

$fs = [system.io.file]::Create("c:\temp\soap.bin")
$writer = [system.xml.xmldictionarywriter]::CreateBinaryWriter($fs)
$xml = [xml] (gc C:\temp\soap.xml)
$xml.Save($writer)
$writer.Close(); $fs.Close()

, WCF :

    @@ -1,7 +1,7 @@
     // client
     static void Main(string[] args)
     {
-        var binding = new CustomBinding(new TextMessageEncodingBindingElement(), 
+        var binding = new CustomBinding(new BinaryMessageEncodingBindingElement(), 
                                         new HttpTransportBindingElement()); 

# 1 397 - . №2 169 gunk. , , . , XmlDictionaryReader WCF!

, ?

+3
4

@MS.

WCF " ", () . , "", " http://www.w3.org/2003/05/soap-envelope", " http://www.w3.org/2005/08/addressing" .. . , , WCF, (IXmlDictionary) XmlDictionaryReader.CreateBinaryReader.

http://msdn.microsoft.com/en-us/library/cc219175(PROT.10).aspx. :

public class Post_e9208540_7877_4318_909d_92eb8490ab58
{
    static XmlDictionary dictionary;
    static XmlDictionary GetDictionary()
    {
        if (dictionary == null)
        {
            XmlDictionary temp = new XmlDictionary();
            dictionary = temp;
            temp.Add("mustUnderstand");
            temp.Add("Envelope");
            temp.Add("http://www.w3.org/2003/05/soap-envelope");
            temp.Add("http://www.w3.org/2005/08/addressing");
            ...
        }
        return dictionary;
    }
    public static void DecodeBinaryMessage(byte[] message)
    {
        XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(message, 0, message.Length, GetDictionary(), XmlDictionaryReaderQuotas.Max);
        Console.WriteLine(reader.ReadOuterXml());
    }
} 

, .

edit: yup, ! , ReadOuterXml() . XmlDocument, , .

. MS 500 . , - http://tfstoys.codeplex.com/sourcecontrol/changeset/view/26191?projectName=tfstoys#499486

+4

..... , BinaryEncoding!

var binding = new CustomBinding(new BinaryMessageEncodingBindingElement(), 
                                new HttpTransportBindingElement());   

- - TextEncoding , ? - WCF , , !:-)

, WCF ?

" " , - gooblydeguck.

WCF , ( ) ( , ). - , WCF, !

:

+1

, , , ServiceModel:

var serviceModelAssembly = Assembly.GetAssembly(typeof (System.ServiceModel.ActionNotSupportedException));
var serviceModelDictionaryType = serviceModelAssembly.GetTypes().Single(t => t.Name.Equals("ServiceModelDictionary"));
var currentVersionProperty = serviceModelDictionaryType.GetProperty("CurrentVersion");
var serviceModelDictionary = (IXmlDictionary)currentVersionProperty.GetValue(null, null);
// Now use serviceModelDictionary as argument for reader
+1

marc_s, , XmlDictionaryReader - , XmlReader ( XmlDictionaryWriter). - InfoSet, - .

/ XML-, BinaryMessageEncoder, , WCF: XmlBinaryReader XmlBinaryWriter. , , , , BinaryMessageEncoder.

, , .

0

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


All Articles