title: Xml-RPC.Net Response Mapping with Struct Arrays
body: <p>I am trying to work with a couple of different XML-RPC API services provided by a third party. I am using the xml-rpc.net library from Cook Computing: <a href="http://xml-rpc.net/" rel="nofollow noreferrer">http://xml-rpc.net/</a></p>
  <h2>TLDR</h2>
  <p>I need help mapping <strong>Array</strong> response types from an XML-RPC API implementation to strongly typed C# objects.</p>
  <h2>Explanation</h2>
  <p>There are 2 different implementations of the xml-rpc spec that are being used, one for each. One is using a fairly easy to work with implementation, using StructParams with a nice logical structure.</p>
  <p>The other one... not so much.</p>
  <p>I have managed to get the requests across reliably, the problem comes with the responses. There are 3 different response types:</p>
  <h2>Status Message</h2>
  <p>This response is not too difficult to work with, it contains a struct with a nested struct and an int, which can be mapped to something like:</p>
  <pre><code>public class Response
  {
      public Result[] Result;
      public int Status;
  }
  
  public struct Result
  {
      public string Status;
  }
  </code></pre>
  <p>The XML in the response which can map as above is:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot;?&gt;
  &lt;methodResponse&gt;
      &lt;params&gt;
          &lt;param&gt;
              &lt;value&gt;
                  &lt;struct&gt;
                      &lt;member&gt;
                          &lt;name&gt;Result&lt;/name&gt;
                          &lt;value&gt;
                              &lt;array&gt;
                                  &lt;data&gt;
                                      &lt;value&gt;
                                          &lt;struct&gt;
                                              &lt;member&gt;
                                                  &lt;name&gt;Status&lt;/name&gt;
                                                  &lt;value&gt;Everything is OK&lt;/value&gt;
                                              &lt;/member&gt;
                                          &lt;/struct&gt;
                                      &lt;/value&gt;
                                  &lt;/data&gt;
                              &lt;/array&gt;
                          &lt;/value&gt;
                      &lt;/member&gt;
                      &lt;member&gt;
                          &lt;name&gt;TransactionID&lt;/name&gt;
                          &lt;value&gt;&lt;i4&gt;123&lt;/i4&gt;&lt;/value&gt;
                      &lt;/member&gt;
                  &lt;/struct&gt;
              &lt;/value&gt;
          &lt;/param&gt;
      &lt;/params&gt;
  &lt;/methodResponse&gt;
  </code></pre>
  <h2>Structure</h2>
  <p>This one gives me a slight problem, but I have been able to overcome it with some nasty extension methods, which I'm not happy with. It's similar to above, but the Result is now an array of an array of values, which I can only visualize as object[][][], so I am mapping it to:</p>
  <pre><code>public struct Response
  {
      public object[][][] Result;
  }
  </code></pre>
  <p>From this, I can then use my extension method which uses reflection to map the individual objects in the final array to a specific struct with the correct types.<br />
  I'm hoping someone can think of a nicer way of doing this. Here's the response XML that I am trying to map:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot;?&gt;
  &lt;methodResponse&gt;
      &lt;params&gt;
          &lt;param&gt;
              &lt;value&gt;
                  &lt;struct&gt;
                      &lt;member&gt;
                          &lt;name&gt;Result&lt;/name&gt;
                          &lt;value&gt;
                              &lt;array&gt;
                                  &lt;data&gt;
                                      &lt;value&gt;
                                          &lt;array&gt;
                                              &lt;data&gt;
                                                  &lt;value&gt;&lt;i4&gt;1&lt;/i4&gt;&lt;/value&gt;
                                                  &lt;value&gt;second slot (string)&lt;/value&gt;
                                                  &lt;value&gt;&lt;double&gt;1.23&lt;/double&gt;&lt;/value&gt;
                                                  &lt;value&gt;&lt;i4&gt;1&lt;/i4&gt;&lt;/value&gt;
                                                  &lt;value&gt;Another string slot&lt;/value&gt;
                                              &lt;/data&gt;
                                          &lt;/array&gt;
                                      &lt;/value&gt;
                                  &lt;/data&gt;
                              &lt;/array&gt;
                          &lt;/value&gt;
                      &lt;/member&gt;
                  &lt;/struct&gt;
              &lt;/value&gt;
          &lt;/param&gt;
      &lt;/params&gt;
  &lt;/methodResponse&gt;
  </code></pre>
  <h2>Array</h2>
  <p>Array responses are where it becomes really tricky. I've not been able to get anything to work reliably with these kinds of responses.</p>
  <p>I have tried adding an extra dimension to the object array as with the struct response, but then I'm left with <code>object[][][][]</code> which I would then have to grab the final 2 dimensions, loop through them and map them to an array of a specific struct. I'm REALLY hoping there's an alternative method that I'm missing here.</p>
  <p>Here's the sample XML for this kind of response:</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot;?&gt;
  &lt;methodResponse&gt;
    &lt;params&gt;
      &lt;param&gt;
        &lt;value&gt;
          &lt;struct&gt;
            &lt;member&gt;
              &lt;name&gt;Result&lt;/name&gt;
              &lt;value&gt;
                &lt;array&gt;
                  &lt;data&gt;
                    &lt;value&gt;
                      &lt;array&gt;
                        &lt;data&gt;
                          &lt;value&gt;
                            &lt;array&gt;
                              &lt;data&gt;
                                &lt;value&gt;
                                  &lt;i4&gt;1&lt;/i4&gt;
                                &lt;/value&gt;
                                &lt;value&gt;Disk Space&lt;/value&gt;
                                &lt;value&gt;MB&lt;/value&gt;
                                &lt;value&gt;
                                  &lt;i4&gt;200&lt;/i4&gt;
                                &lt;/value&gt;
                                &lt;value&gt;
                                  &lt;double&gt;0.000000&lt;/double&gt;
                                &lt;/value&gt;
                                &lt;value&gt;
                                  &lt;i4&gt;0&lt;/i4&gt;
                                &lt;/value&gt;
                              &lt;/data&gt;
                            &lt;/array&gt;
                          &lt;/value&gt;
                          &lt;value&gt;
                            &lt;array&gt;
                              &lt;data&gt;
                                &lt;value&gt;
                                  &lt;i4&gt;2&lt;/i4&gt;
                                &lt;/value&gt;
                                &lt;value&gt;Traffic&lt;/value&gt;
                                &lt;value&gt;GB&lt;/value&gt;
                                &lt;value&gt;
                                  &lt;i4&gt;20&lt;/i4&gt;
                                &lt;/value&gt;
                                &lt;value&gt;
                                  &lt;double&gt;1.000000&lt;/double&gt;
                                &lt;/value&gt;
                                &lt;value&gt;
                                  &lt;i4&gt;0&lt;/i4&gt;
                                &lt;/value&gt;
                              &lt;/data&gt;
                            &lt;/array&gt;
                          &lt;/value&gt;
                        &lt;/data&gt;
                      &lt;/array&gt;
                    &lt;/value&gt;
                  &lt;/data&gt;
                &lt;/array&gt;
              &lt;/value&gt;
            &lt;/member&gt;
          &lt;/struct&gt;
        &lt;/value&gt;
      &lt;/param&gt;
    &lt;/params&gt;
  &lt;/methodResponse&gt;
  </code></pre>
  <p>Any pointers on how to map these kinds of responses simply and correctly would be appreciated.</p>
  <p>Thanks,
  James.</p>