views:

63

answers:

1

I am working on a Windows Phone 7 app that talks to a 3rd party Soap service. I used 'Add Service Reference' to the wsdl to generate the proxy class. Some calls work, but certain outbound calls that make use of an 'sObject' class result in the error "The type System.Xml.Linq.XElement was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically"

The relevant part of the sObject class is defined (as autogenerated)

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:sobject.partner.soap.sforce.com")]
 public partial class sObject : object, System.ComponentModel.INotifyPropertyChanged {

    <snipped ....>

    [System.Xml.Serialization.XmlAnyElementAttribute(Namespace="urn:sobject.partner.soap.sforce.com", Order=3)]
    public System.Xml.Linq.XElement[] Any {
        get {
            return this.anyField;
        }
        set {
            this.anyField = value;
            this.RaisePropertyChanged("Any");
        }
    }

The code I use to create a sObject:

sObject post = new sObject();
        XElement postEls = new XElement("sObject",
            new XElement("Type", "TextPost"),
            new XElement("ParentId", userInfo.userId),
            new XElement("Body", postBody)
            );

        post.Any = postEls.Elements().ToArray();

Steps I Have Tried:

Adding [System.Xml.Serialization.XmlInclude(typeof(System.Xml.Linq.XElement))] to the sObject class. Same error, it seems like this should have worked.

Adding [System.Xml.Serialization.XmlElement()] to the Any property. When I did this the message was serialized, but -as expected- incorrect (the Any elements should not be there, the goal is just the XElements[] as output)

 <sObject>
      <type xmlns="urn:sobject.partner.soap.sforce.com">FeedPost</type>
      <Id xsi:nil="true" xmlns="urn:sobject.partner.soap.sforce.com" />
      <Any xmlns="urn:sobject.partner.soap.sforce.com">
        <Type xmlns="">TextPost</Type>
      </Any>
      <Any xmlns="urn:sobject.partner.soap.sforce.com">
        <ParentId xmlns="">XXXXXX</ParentId>
      </Any>
      <Any xmlns="urn:sobject.partner.soap.sforce.com">
        <Body xmlns="">Test post from WP7!</Body>
      </Any>
    </sObject>

As an aside, I suspect this is related, calls that return sObjects inbound from the 3rd party service have their Any property null, despite the data being there in the RPC Response.

A: 

It turns out the exception was due to the serialization of XElement[], currently an issue in Windows Phone 7.

As noted by Vijay Verma here, The linked MSDN article on XmlSerializer.Serialize states under Platform Notes:

Silverlight for Windows Phone: The XmlSerializer.Serialize method throws an InvalidOperationException if the XmlSerializer object is initialized with a type parameter that contains an array of objects of type XElement.

Vijay listed a workaround of using a single XElement and parsing the field separately. This would work if you control both sides of the SOAP message. Unfortunately I do not so the request is invalid on the 3rd party's side.

This explains the InvalidOperationException with XElement was not expected, although not the answer I was hoping for. Hopefully it helps someone else who may have control over both sides of the service.

George Babey
George, edit your original question with this data instead of adding an "answer" that isn't an answer. This is not a discussion forum.
John Saunders
John, I've reformatted my answer to be structured as an answer.
George Babey