Отображение ответов Xml-RPC.Net с помощью структурных массивов - PullRequest
1 голос
/ 30 марта 2012

Я пытаюсь работать с парой различных сервисов API XML-RPC, предоставляемых третьей стороной. Я использую библиотеку xml-rpc.net от Cook Computing: http://xml -rpc.net /

TLDR

Мне нужна помощь для сопоставления Array типов ответов от реализации API XML-RPC со строго типизированными объектами C #.

Объяснение

Существует 2 разных реализации спецификации xml-rpc, по одной для каждой. Одним из них является использование довольно простой работы с реализацией, использование StructParams с хорошей логической структурой.

Другой ... не так много.

Мне удалось надежно передать запросы, проблема связана с ответами. Существует 3 различных типа ответов:

Сообщение о состоянии

Этот ответ не слишком сложен для работы, он содержит структуру с вложенной структурой и int, которые могут быть сопоставлены с чем-то вроде:

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

public struct Result
{
    public string Status;
}

XML в ответе, который может отображаться, как указано выше:

<?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>

Структура

Это дает мне небольшую проблему, но я смог преодолеть ее с помощью некоторых противных методов расширения, которые меня не устраивают. Это похоже на приведенное выше, но Result теперь является массивом массива значений, который я могу визуализировать только как object [] [] [], поэтому я сопоставляю его с:

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

После этого я могу использовать свой метод расширения, который использует отражение, чтобы отобразить отдельные объекты в конечном массиве в конкретную структуру с правильными типами.
Я надеюсь, что кто-то может придумать более хороший способ сделать это. Вот XML-код ответа, который я пытаюсь отобразить:

<?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>

Массив

Ответы в массиве - вот где все становится действительно сложно. Я не смог заставить что-либо надежно работать с такими ответами.

Я попытался добавить дополнительное измерение к массиву объектов, как и в случае ответа struct, но затем у меня остался object[][][][], который я должен был бы затем взять в двух последних измерениях, пройти через них и отобразить их в массив конкретной структуры. Я ДЕЙСТВИТЕЛЬНО надеюсь, что есть альтернативный метод, который мне здесь не хватает.

Вот пример XML для такого ответа:

<?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>

Буду признателен за любые указания о том, как просто и правильно отобразить ответы такого типа.

Спасибо, Джеймс.

1 Ответ

2 голосов
/ 01 апреля 2012

XML-RPC.NET в настоящее время не поддерживает сопоставление массивов с классом или структурным типом, хотя в принципе нет ничего, что могло бы предотвратить это (т. Е. Вы могли бы аннотировать членов класса / структуры с их порядком в массиве, используя новый версия атрибута XmlRpcMember и изменение сериализатора / десериализатора). Но сейчас вы должны сделать что-то похожее на то, что вы предложили, хотя я думаю, что вы неправильно указали размеры массива и типы должны быть определены следующим образом:

Сообщение о состоянии

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

public struct Result
{
  public string Status;
}

Структура

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

Массив

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