Xml-RPC.Net Response Mapping with Struct Arrays

让人想犯罪 __ 提交于 2019-12-14 02:37:48

问题


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: http://xml-rpc.net/

TLDR

I need help mapping Array response types from an XML-RPC API implementation to strongly typed C# objects.

Explanation

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.

The other one... not so much.

I have managed to get the requests across reliably, the problem comes with the responses. There are 3 different response types:

Status Message

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:

public class Response
{
    public Result[] Result;
    public int Status;
}

public struct Result
{
    public string Status;
}

The XML in the response which can map as above is:

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <struct>
                    <member>
                        <name>Result</name>
                        <value>
                            <array>
                                <data>
                                    <value>
                                        <struct>
                                            <member>
                                                <name>Status</name>
                                                <value>Everything is OK</value>
                                            </member>
                                        </struct>
                                    </value>
                                </data>
                            </array>
                        </value>
                    </member>
                    <member>
                        <name>TransactionID</name>
                        <value><i4>123</i4></value>
                    </member>
                </struct>
            </value>
        </param>
    </params>
</methodResponse>

Structure

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:

public struct Response
{
    public object[][][] Result;
}

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.
I'm hoping someone can think of a nicer way of doing this. Here's the response XML that I am trying to map:

<?xml version="1.0"?>
<methodResponse>
    <params>
        <param>
            <value>
                <struct>
                    <member>
                        <name>Result</name>
                        <value>
                            <array>
                                <data>
                                    <value>
                                        <array>
                                            <data>
                                                <value><i4>1</i4></value>
                                                <value>second slot (string)</value>
                                                <value><double>1.23</double></value>
                                                <value><i4>1</i4></value>
                                                <value>Another string slot</value>
                                            </data>
                                        </array>
                                    </value>
                                </data>
                            </array>
                        </value>
                    </member>
                </struct>
            </value>
        </param>
    </params>
</methodResponse>

Array

Array responses are where it becomes really tricky. I've not been able to get anything to work reliably with these kinds of responses.

I have tried adding an extra dimension to the object array as with the struct response, but then I'm left with object[][][][] 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.

Here's the sample XML for this kind of response:

<?xml version="1.0"?>
<methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>Result</name>
            <value>
              <array>
                <data>
                  <value>
                    <array>
                      <data>
                        <value>
                          <array>
                            <data>
                              <value>
                                <i4>1</i4>
                              </value>
                              <value>Disk Space</value>
                              <value>MB</value>
                              <value>
                                <i4>200</i4>
                              </value>
                              <value>
                                <double>0.000000</double>
                              </value>
                              <value>
                                <i4>0</i4>
                              </value>
                            </data>
                          </array>
                        </value>
                        <value>
                          <array>
                            <data>
                              <value>
                                <i4>2</i4>
                              </value>
                              <value>Traffic</value>
                              <value>GB</value>
                              <value>
                                <i4>20</i4>
                              </value>
                              <value>
                                <double>1.000000</double>
                              </value>
                              <value>
                                <i4>0</i4>
                              </value>
                            </data>
                          </array>
                        </value>
                      </data>
                    </array>
                  </value>
                </data>
              </array>
            </value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodResponse>

Any pointers on how to map these kinds of responses simply and correctly would be appreciated.

Thanks, James.


回答1:


XML-RPC.NET doesn't currently support mapping arrays onto a class or struct type, though there is nothing in principal to prevent this (i.e. you could annotate the class/struct members with their order in the array using a new version of the XmlRpcMember attribute and modify the serializer/deserializer). But for now you have to do something similar to what you suggested, though I think you got the array dimensions wrong and the types should be defined like this:

Status Message

public class StatusResponse
{
  public Result[] Result;
  public int TransactionID;
}

public struct Result
{
  public string Status;
}

Structure

public struct StructureResponse
{
  public object[][] Result;
}

Array

public struct ArrayResponse
{
  public object[][][] Result;
}


来源:https://stackoverflow.com/questions/9945863/xml-rpc-net-response-mapping-with-struct-arrays

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!