simple-odata-client / Simple.OData.Client

MIT License
330 stars 196 forks source link

OData connection SuccessFactors - Exception reading in Metadata (Annotations) #75

Closed richardlacelle closed 9 years ago

richardlacelle commented 9 years ago

Getting an exception when trying to make an OData connection to SAP's SuccessFactors.

"The metadata document could not be read from the message content.\r\nUnexpectedXmlElement : The schema element 'Annotation' was not expected in the given context. : (1, 522)\r\nTextNotAllowed : The current schema element does not support text 'Address 1'. : (1, 554)\r\n"

Here's a snipped of their metadata xml being returned.

I don't mind paying you for your timing debugging this.

Thanks

Address 1
object commented 9 years ago

Hi Richard, The snippet didn't make it, I can't see the metadata XML. Can you try again or just send metadata to vagif.abilov@gmail.com.

Thanks!

object commented 9 years ago

The metadata schema is invalid because of two unsupported items but they can be removed at interception stage using AfterResponse handler. Here's an implementation of AfterReponse handler that I quickly wrote:

    private static void AfterResponse(HttpResponseMessage responseMessage)
    {
        if (responseMessage.RequestMessage.RequestUri.LocalPath.EndsWith("$metadata"))
        {
            var metadata = responseMessage.Content.ReadAsStringAsync().Result;
            var doc = new XmlDocument();
            doc.LoadXml(metadata);

            var manager = new XmlNamespaceManager(doc.NameTable);
            manager.AddNamespace("ns", "http://schemas.microsoft.com/ado/2008/09/edm");
            var nodes = doc.SelectNodes("//ns:Annotation", manager);
            for (var i = nodes.Count - 1; i >= 0; i--)
            {
                nodes[i].ParentNode.RemoveChild(nodes[i]);
            }

            nodes = doc.SelectNodes("//ns:Property[@CollectionKind]", manager);
            for (var i = 0; i < nodes.Count; i++)
            {
                nodes[i].Attributes.Remove(nodes[i].Attributes["CollectionKind"]);
            }

            using (var stringWriter = new StringWriter())
            using (var xmlTextWriter = XmlWriter.Create(stringWriter))
            {
                doc.WriteTo(xmlTextWriter);
                xmlTextWriter.Flush();
                metadata = stringWriter.GetStringBuilder().ToString();
            }

            var byteArray = Encoding.UTF8.GetBytes(metadata);
            var stream = new MemoryStream(byteArray);
            stream.Position = 0;
            var content = new StreamContent(stream);
            foreach (var header in responseMessage.Content.Headers)
            {
                if (header.Key != "Content-Length")
                    content.Headers.Add(header.Key, header.Value);
            }
            content.Headers.Add("Content-Length", metadata.Length.ToString());
            responseMessage.Content = content;
        }
    }