Serialization 如何使用RestSharp将对象(作为XML)发布到ApicController?

Serialization 如何使用RestSharp将对象(作为XML)发布到ApicController?,serialization,asp.net-web-api,restsharp,Serialization,Asp.net Web Api,Restsharp,我有一个ASP.NETMVC4网站,它实现了一个RESTAPI,我从客户端应用程序中使用它。我的ApiController方法接受并返回复杂的对象,如XML 我最近发现了RestSharp,并开始将我的客户项目转移到这一点上。然而,我有真正的问题。这似乎几乎奏效了——它离我太近了,我几乎可以尝到成功的滋味——但我就是不能让它100%奏效 我穿过导线的对象看起来像这样: // The object I'm passing across the wire public class Example {

我有一个ASP.NETMVC4网站,它实现了一个RESTAPI,我从客户端应用程序中使用它。我的ApiController方法接受并返回复杂的对象,如XML

我最近发现了RestSharp,并开始将我的客户项目转移到这一点上。然而,我有真正的问题。这似乎几乎奏效了——它离我太近了,我几乎可以尝到成功的滋味——但我就是不能让它100%奏效

我穿过导线的对象看起来像这样:

// The object I'm passing across the wire
public class Example
{
    bool IsActive { get; set; }
    string Name { get; set; }
}
// 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);
我的ApicController方法如下所示:

// The object I'm passing across the wire
public class Example
{
    bool IsActive { get; set; }
    string Name { get; set; }
}
// 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);
当我尝试将一个对象发布到我的网站时,会出现以下问题:

// The object I'm passing across the wire
public class Example
{
    bool IsActive { get; set; }
    string Name { get; set; }
}
// 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);
…这就是我得到的:

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

福
真的
这显然是不好的,尤其是因为它从XML声明开始,我认为这会导致问题。没有办法关闭它,因为RestSharp派生类没有提供这样做的方法。此外,没有名称空间——无论我如何尝试在RestSharp中设置名称空间(在DotNetXmlSerializer的构造函数中,通过设置名称空间成员,或通过将名称空间传递给AddBody),都无法在输出中显示名称空间。在我看来,这门课只不过是一个陷阱

看起来我唯一的选择是创建自己的序列化程序类并在内部使用DataContractSerializer。是这样,还是我遗漏了什么


(顺便说一句,我可以将请求的RequestFormat设置为JSON,它可以正常工作——但我仍然想知道如何使用XML来实现这一点)。

我遇到了一些AddBody调用无法正确序列化JSON值的问题,因此可能与您的问题有些相似。代替AddBody,您可以尝试:

request.AddParameter("text/xml", xmlAsString, ParameterType.RequestBody);
如果这样做有效,您可以查看如何将第二个参数更改为xml对象,并查看序列化程序是否满足您的要求


另一个选项可能是
XmlMediaTypeFormatter。ReadFromStreamAsync
没有正确地获取正确的序列化程序;您可以尝试重写该函数。

上述问题是因为WebAPI使用的是DataContractSerializer(而不是您所追求的XmlSerializer)。要切换此选项,请修改Global.asax,如下所示

 var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
 xml.UseXmlSerializer = true;
但是,我建议您使用WebAPI的RESTSharp格式化程序(而不是使用.Net格式化程序)。如果您希望DTO具有循环引用(.net fx序列化程序不能很好地处理此问题),则这一点尤其有用

在Global.asax中,通过输入

GlobalConfiguration.Configuration.Formatters.XmlFormatter=//此处为RestSharp XML序列化程序


WebAPI中序列化的快速概述

您必须使用RestSharp吗?@CuongLe:ha!我最初使用DataContractSerializer开发自己的产品,然后被同事说服使用RestSharp。我可以切换到另一种解决方案,但我现在已经投入了太多时间试图让RestSharp工作,所以我不愿意这样做。正如我在回答中所暗示的,我最终改用JSON而不是XML,所以这个问题主要是为了其他人的利益。@Gary,我认为JSON是像RESTSharp这样的库真正擅长的地方,在性能方面你也会得到一点性能提升。