RestSharp Deserialize返回空属性,但xml.deserialize测试有效

时间:2012-11-26 08:50:30

标签: c# xml xml-serialization restsharp

编辑:我问你想要尝试的问题的那一刻...... 我已经在请求上设置了XmlNamespace属性,并且这样做了。

request.XmlNamespace = "http://musicbrainz.org/ns/mmd-2.0#";

但我真的不明白为什么......

下一个问题是让RestSharp将xml属性识别为对象属性


在周末的大部分时间里,我一直在讨论这个问题,而我却无法让它发挥作用。

我正在尝试围绕RestFul webservice(MusicBrainz)编写一个包装器。我正在测试一个简单的例子:获取一位艺术家的详细信息并将其放入自定义的Artist对象中。

当我在RestClient上执行Execute时,它结束了,但我的对象属性为null。 但是当我使用XmlDeserializer测试反序列化时,objectproperties被填充(但不是对应于属性的属性,但我稍后会解决)

响应的反序列化和将对象放在response.data之间会发生什么? 很可能这是我正在制作的“新手”错误,因为这是我使用RestSharp的第一步......

非常感谢帮助..

退回xml:

<metadata>
   <artist type="Group" id="f1548c5b-329e-4036-921c-02213a04b525">
       <name>Uriah Heep</name>
           <sort-name>Uriah Heep</sort-name>
           <country>GB</country>
           <life-span>
               <begin>1970</begin>
           </life-span>
    </artist>
</metadata>

我的课程:

public class Artist
{
    public int Id { get; set; }
    public string Type { get; set; }
    public string Name { get; set; }
    public string SortName { get; set; }
    public string Country { get; set; }

}

在以下代码中输出属性已填充

var output = xml.Deserialize<Artist>(response);

但是在调用

时,相同的响应不会填充属性
var response = client.Execute<T>(request);

完整代码(为了简单起见,我将测试代码放在通用方法中):

public T Execute<T>(RestRequest request) where T : new()
{
    var client = new RestClient();
    client.BaseUrl = BaseUrl;
    client.Authenticator = null;

    //does not fill properties 
    var response = client.Execute<T>(request);

    if (response.ErrorException != null)
    {
        throw response.ErrorException;
    }
    var xml = new XmlDeserializer();

    //fills properties
    var output = xml.Deserialize<Artist>(response);

    return response.Data;
}

1 个答案:

答案 0 :(得分:0)

这是因为Execute方法在收到响应后,会尝试根据请求的RootElement和XmlNamespace属性协商,并将它们复制到{{ 1}}。

以下是代码from RestClient

XmlDeserializer

如果使用不匹配的XmlNamespace传递RestRequest,则RestSharp的 handler.RootElement = request.RootElement; handler.DateFormat = request.DateFormat; handler.Namespace = request.XmlNamespace; response.Data = handler.Deserialize<T>(raw); (在后台使用XDocument)将无法将响应XML映射到对象属性,您将获得默认值/ null值。

现在用于默认实现(当您手动创建XmlDeserializer时),如果您未设置XmlNamespace,则反序列化器将执行自动检测,它基本上忽略响应中的所有命名空间并仅按名称映射所有属性。

请参阅源代码from XmlDeserializer

XmlDeserializer

考虑到以上所有因素,很清楚为什么在您使用以下行将XmlNamespace属性显式设置为请求对象中的匹配命名空间之后它开始工作:

     // autodetect xml namespace
     if (!Namespace.HasValue())
     {
         RemoveNamespace(doc);
     }

request.XmlNamespace = "http://musicbrainz.org/ns/mmd-2.0#"; 方法将名称空间复制到反序列化程序中,并将XML映射到对象。