Как я могу POST (как XML) объект к моему ApiController, используя RestSharp?

У меня есть веб-сайт ASP.NET MVC4, реализующий API REST, который я использую из клиентского приложения. Мои методы ApiController принимают и возвращают сложные объекты в виде XML.

Недавно я обнаружил RestSharp и начал перекладывать свой клиентский проект на это. Однако у меня есть реальные проблемы с этим. Кажетсяalmost работа - это так близко, что я почти чувствую вкус успеха - но я просто не могу заставить его работать на 100%.

Объекты, которые я передаю через провод, выглядят примерно так:

// The object I'm passing across the wire
public class Example
{
    bool IsActive { get; set; }
    string Name { get; set; }
}

Мой метод ApiController выглядит так:

// My ApiController method
public HttpResponseMessage PostExample(Example example)
{
    if (ModelState.IsValid)
    {
        db.Examples.Add(example);

        db.SaveChanges();

        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, example);

        return response;
    }
    else
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }
}

Проблема возникает, когда я пытаюсь разместить объект на моем сайте, например:

var example = new Example () { IsActive = true, Name = "foo" };

var request = new RestSharp.RestRequest("/api/example", RestSharp.Method.POST);

request.AddBody(example, XmlNamespace);

var client = new RestClient();

client.BaseUrl = "foo.com";

var response = client.Execute<Example>(request);

Приведенный выше код выполняет метод PostExample в моем ApiController, и в качестве параметра у него есть объект Example.However значения свойств объекта Example не совпадают со значениями, которые я передал методу Execute! В одном случае член IsActive был ложным, а не истиной, хотя я также видел случай, когда член имени был нулевым, где он должен был иметь значение.

Я провел некоторое исследование с использованием Fiddler, и кажется, что правильные значенияare создается в XML, который генерирует RestSharp. Тем не менее, XML не совсем в том же формате, который веб-сервер выдает при выполнении GET. Различия невелики, но, похоже, делают различие между тем, что работает, а что нет. Платформа на стороне веб-сервера, кажется, чувствительна к этим различиям форматирования и в результате неправильно интерпретирует XML.

Вот XML, который я получаю от RestSharp:

<Example xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace">
  <Name>foo</Name>
  <IsActive>true</IsActive>
</Example>

Вот что я получаю при выполнении GET на веб-сервере (или при сериализации с использованием DataContractSerializer, что я и делал ранее):

<Example xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace">
  <IsActive>true</IsActive>
  <Name>foo</Name>
</TagDto>

Версия RestSharp имеет следующие отличия от версии DataContractSerializer:

Fields are in a different order RestSharp doesn't include the extra namespace XMLSchema-instance namespace DataContractSerializer doesn't include any spaces or line-breaks (I added those above for readability)

Я удивлен, что любой из них имеет большое значение, но ясно, что они делают. Также обратите внимание, что до тех пор, пока я не добавил явное пространство имен в вызове AddBody, оно отсутствовало в сгенерированном XML (очевидно), и объект Example, переданный в мой ApiController, былnull.

В любом случае, я заметил, что RestSharp позволяет вам переопределять сериализатор и предоставляет способ использования .NET XML сериализатора. Я пытался использовать это (безрезультатно).

Это то, что я добавил перед вызовом AddBody:

request.XmlSerializer = new RestSharp.Serializers.DotNetXmlSerializer(XmlNamespace);

..и вот что я получаю:

<?xml version="1.0" encoding="utf-8"?>
<Example>
  <Name>foo</Name>
  <IsActive>true</IsActive>
</Example>

Это явно не хорошо, не в последнюю очередь потому, что начинается с объявления XML, которое я представляюwould вызвать проблемы. Отключить это невозможно, потому что производный класс RestSharp не предоставляет этого. Кроме того, нет пространства имен - и я не могу заставить его появляться в выходных данных, независимо от того, как я пытаюсь установить пространство имен в RestSharp (в конструкторе для DotNetXmlSerializer, устанавливая член пространства имен или передавая пространство имен для AddBody). На мой взгляд, этот класс - не более чем ловушка.

Похоже, мой единственный вариант - создать свой собственный класс сериализатора и использовать DataContractSerializer внутри. Это правильно, или я что-то упустил?

(Кстати, я могу установить RequestFormat запроса в JSON, и он просто работает, но я все еще хотел бы знать, как заставить это работать с XML).

Ответы на вопрос(2)

Ваш ответ на вопрос