SirJames
SirJames

Reputation: 49

WP7 - Building an XML Message

I need to send an XML message to a web service for my WP7 app, but I have no experience doing that.

This is the format in which the web service needs me to send the XML:

<pfpMessage version='1.5'>
 <header>
    <source>
      <component type="pfsvc" role="master">
        <host ip="" hostname="" serverId=""/>
      </component>
    </source>
  </header>
  <request request-id='1288730909' async='0' response-url='' language='en'>
    <phoneAppValidateDeviceTokenRequest >
      <phoneAppContext >
        <guid>...</guid>
        <deviceToken >...</deviceToken>
        <version >1.0.0</version>
      </phoneAppContext>
      <validationResult >yes</validationResult>
    </phoneAppValidateDeviceTokenRequest>
  </request>
</pfpMessage>

And this is a small section of the code I have written:

    XDocument doc = new XDocument();

    // start message
    XElement root = doc.Element("pfpMessage");
    root.SetAttributeValue("version", 1.5);
    doc.Add(root);

    // message header
    XElement header = doc.Element("header");
    root.Add(header);
    XElement source = doc.Element("source");
    header.Add(source);
    XElement component = doc.Element("component");
    component.SetAttributeValue("type", "pfsdk");
    source.Add(component);
    XElement element = doc.Element("host");
    element.SetAttributeValue("ip", pfAuthParams.IpAddress);
    element.SetAttributeValue("hostname", pfAuthParams.Hostname);
    component.Add(element);

Part of the problem is that the SetAttributeValue function keeps throwing an exception even though it looks exactly the same as the MSDN example.

Is this the right way to build an XML message that matches the format?

EDIT: This causes an InvalidOperationException:

XDocument doc = new XDocument(
            new XElement("pfpMessage",
                new XAttribute("version", 1.5),
                new XElement("header",
                    new XElement("source",
                        new XElement("component",
                            new XAttribute("type", "pfsdk"),
                            new XElement("host",
                                new XAttribute("ip", pfAuthParams.IpAddress),
                                new XAttribute("hostname", pfAuthParams.Hostname)
                            )
                        )
                    )
                )
            ),
            new XElement("request",
                new XAttribute("request-id", y),
                new XAttribute("async", 0),
                new XAttribute("response-url", ""),
                new XAttribute("language", "en"),
                new XElement("phoneAppValidateDeviceTokenRequest",
                    new XElement("phoneAppValidateContext"),
                    new XElement("guid", (Application.Current as App).SharedGUID),
                    new XElement("deviceToken", (Application.Current as App).SharedURI)
                    ),
                    new XElement("version", "1.0.0")
                )                   
        );

Upvotes: 0

Views: 124

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1502386

Here:

XElement root = doc.Element("pfpMessage");
root.SetAttributeValue("version", 1.5);

... you're assuming that the element already exists. The Element method finds an element in the container you call it on. You've only just created the document, so it's empty. You need to create a new element:

XElement root = new XElement("pfpMessage");

Likewise everywhere else.

Here's a clearer way of doing it:

XDocument doc = new XDocument(
    new XElement("pfpMessage",
        new XAttribute("version", 1.5),
        new XElement("header",
            new XElement("source",
                new XElement("component",
                    new XAttribute("type", "pfsdk"),
                    new XElement("host",
                        new XAttribute("ip", pfAuthParams.IpAddress),
                        new XAttribute("hostname", pfAuthParams.Hostname)
                    )
                )
            )
        )
    )
);

(Obviously you can collapse the brackets at the end if you want.)

This is a more declarative way of constructing the document - it's closer to the spirit of LINQ to XML. Of course you can manually create each element separately and attach it to the parent, but it's more long-winded.

Upvotes: 2

Related Questions