问题
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