简体   繁体   English

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

[英]RestSharp Deserialize returns empty properties but xml.deserialize test works

EDIT : the moment I asked the question I thougt of trying something.. I've set XmlNamespace property on the request and that did the trick.. 编辑:当我问我尝试某事的问题时......我已经在请求上设置了XmlNamespace属性,这就是诀窍..

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

But I don't really understand as to why... 但我真的不明白为什么......

Next problem is getting RestSharp to recognize xml atributes as object properties 下一个问题是让RestSharp将xml属性识别为对象属性


I've been going over this for the most of the weekend and I just don't get it to work. 在周末的大部分时间里,我一直在讨论这个问题,而我却没有让它发挥作用。

I'm trying to write a wrapper round a RestFul webservice (MusicBrainz). 我正在尝试围绕RestFul webservice(MusicBrainz)编写一个包装器。 I'm testing with a simple example : get details of one artist and put it in a custom Artist object. 我正在测试一个简单的例子:获取一位艺术家的详细信息并将其放入自定义的Artist对象中。

When I do a Execute on the RestClient it ends ok but my object properties are null.. But when I test the deserialization with the XmlDeserializer the objectproperties are filled (But not for properties that correspond to an attribute, but I'll tackle that later) 当我在RestClient上执行Execute时,它结束了,但我的对象属性为null。但是当我使用XmlDeserializer测试反序列化时,objectproperties被填充(但不是对应于属性的属性,但我稍后会解决这个问题) )

What happens between deserialization of the response and putting the object in response.data ? 在响应的反序列化和将对象放在response.data之间会发生什么? Quite possible it is a "newbie" error I'm making as this are my first steps with RestSharp.. 很可能这是我正在制作的“新手”错误,因为这是我使用RestSharp的第一步。

Help would be much appreciated.. 帮助将不胜感激..

Returnded xml : 退回的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>

My class : 我的课 :

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; }

}

In the following code output properties are filled 在以下代码中输出属性已填充

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

But the same response does not fill properties when calling 但是同样的响应在调用时不会填充属性

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

Complete code (I've put the test code in the generic method for sake of simplicity) : 完整代码(为了简单起见,我将测试代码放在通用方法中):

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;
}

This happens because Execute method, after receiving response, tries to negotiate it based on the request's RootElement and XmlNamespace properties and copies them to the XmlDeserializer . 发生这种情况是因为Execute方法在接收到响应后,会尝试根据请求的RootElement和XmlNamespace属性进行协商 ,并将它们复制XmlDeserializer

Here's a code from RestClient : 这是RestClient的代码:

     handler.RootElement = request.RootElement;
     handler.DateFormat = request.DateFormat;
     handler.Namespace = request.XmlNamespace;
     response.Data = handler.Deserialize<T>(raw);

If you pass a RestRequest with a mismatching XmlNamespace, RestSharp's XmlDeserializer (that uses XDocument behind the scenes) won't be able to map response XML to an object properties and you will get default/null values instead. 如果使用不匹配的XmlNamespace传递RestRequest,则RestSharp的XmlDeserializer (在后台使用XDocument)将无法将响应XML映射到对象属性,您将获得默认值/ null值。

Now for default implementation (when you create XmlDeserializer manually), if you don't set a XmlNamespace, deserializer will do an auto-detection that basically ignores all namespaces in the response and maps all properties only by their names. 现在对于默认实现(当您手动创建XmlDeserializer ),如果未设置XmlNamespace,则反序列化器将执行自动检测 ,该检测基本上忽略响应中的所有命名空间,并仅根据其名称映射所有属性。

See source code from XmlDeserializer : 请参阅XmlDeserializer的源代码:

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

Taking all above into account, it's clear why it started working after you explicitly set XmlNamespace property to a matching namespace in your request object with this line: 考虑到以上所有因素,很清楚为什么在您使用以下行将XmlNamespace属性显式设置为请求对象中的匹配命名空间后,它开始工作:

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

Execute method copied namespace into deserializer and it mapped XML to object appropriately. Execute方法将名称空间复制到反序列化器中,并将XML映射到对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM