XmlReader.ReadContentAsBase64() fails. Base64 encoded data expected. Found end element

783 views Asked by At

In my WCF formatter, I have a Base64 Content wrapped in an XML-Element <Binary>...</Binary>

My Code:

bodyReader.ReadFullStartElement("Binary");
byte[] rawBody = bodyReader.ReadContentAsBase64();

fails with the Exception:
"System.Xml.XmlException: Base64 encoded data expected. Found end element '' from namespace ''.

To be exact 'bodyReader' is an XmlDictionaryReader.
ReadContentAsBase64() @ MSDN
ReadFullStartElement() @MSDN

Surprisingly, the following workaround works:

bodyReader.ReadFullStartElement("Binary");
string b64 = bodyReader.ReadContentAsString();
rawBody = Convert.FromBase64String(b64);

though, this Workaround is fine for me,
I'd like to know what am i doing wrong?

Edit:

Tried to reproduce on a minimal example, though the following example fails
Note: the Base64 string is the one failing on the DispatchFormatter

private void TestXmlDictionaryReader()
    {
        string base64 = @"ewpjbGFzc05hbWU6ICJFYmF5IiwKc2hvcE5hbWU6ICJUb21lclNCIgp2YWx1ZTo1Cn0=";
        string s = @"<Binary>ewpjbGFzc05hbWU6ICJFYmF5IiwKc2hvcE5hbWU6ICJUb21lclNCIgp2YWx1ZTo1Cn0=</Binary>";
        StringReader sr = new StringReader(s);
        var xr = XmlReader.Create(sr);
        var xmlDictRdr = XmlDictionaryReader.CreateDictionaryReader(xr);
        xr.ReadStartElement("Binary");
        byte[] buff = new byte[5000];
        xr.ReadContentAsBase64(buff, 0, 0);
    }

2nd thing, ReadContentAsBase64 signature is different.

Minimal Reproducable Example because it didn't work as a simple method, I created a basic WCF project with my (Crippled) Dispatch formatter: Here on my GoogleDrive

Place Breakpoint @ NewtonsoftJsonDispatchFormatter.cs Line 42.

42: var bodyReader = message.GetReaderAtBodyContents();
43: bodyReader.ReadStartElement("Binary");
44: byte[] rawBody = bodyReader.ReadContentAsBase64();

use any method to send a POST request to your service:

POST /Service1.svc/GetData HTTP/1.1
Host: localhost:1227
Cache-Control: no-cache
Postman-Token: 6d7141b8-c6c8-a9c1-f669-06c3c0ccd5e2

{
  className: "Ebay",
  shopName: "TomerSB"
  value:5
}
1

There are 1 answers

0
Mohammad On

I'm not sure but i guess the API controller will serialize the string as a XML string literal, which will cause the string to be wrapped in double quotes and cause any other special characters inside the string to escaped with a backslash. so when you try to convert it to byte array it throws exception.