7

編集:私が何かをしようと思った質問をした瞬間..リクエストにXmlNamespaceプロパティを設定しましたが、それでうまくいきました..

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

しかし、その理由はよくわかりません...

次の問題は、RestSharp に xml 属性をオブジェクト プロパティとして認識させることです。


私は週末のほとんどの間これを調べてきましたが、うまくいきません。

RestFul ウェブサービス (MusicBrainz) のラッパーを作成しようとしています。簡単な例でテストしています: 1 人のアーティストの詳細を取得し、それをカスタム Artist オブジェクトに入れます。

RestClient で Execute を実行すると問題なく終了しますが、オブジェクト プロパティは null です。しかし、XmlDeserializer を使用して逆シリアル化をテストすると、オブジェクト プロパティが満たされます (ただし、属性に対応するプロパティではありませんが、後で対処します) )

応答の逆シリアル化とオブジェクトの 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;
}
4

1 に答える 1

0

これは、Executeメソッドが応答を受け取った後、要求の RootElement プロパティと XmlNamespace プロパティに基づいてネゴシエートを試み、それらを .xml ファイルにコピーするために発生しXmlDeserializerます。

RestClientのコードは次のとおりです。

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

一致しない XmlNamespace で RestRequest を渡すと、RestSharp XmlDeserializer(バックグラウンドで XDocument を使用する) は応答 XML をオブジェクト プロパティにマップできず、代わりにデフォルト/null 値を取得します。

デフォルトの実装 (XmlDeserializer手動で作成する場合) では、XmlNamespace を設定しない場合、デシリアライザーは自動検出を行い、基本的に応答内のすべての名前空間を無視し、すべてのプロパティをその名前だけでマップします。

XmlDeserializer のソース コードを参照してください。

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

上記のすべてを考慮に入れると、次の行で XmlNamespace プロパティをリクエスト オブジェクトの対応する名前空間に明示的に設定した後、なぜ機能し始めたのかは明らかです。

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

Executeメソッドは名前空間をデシリアライザーにコピーし、XML をオブジェクトに適切にマッピングしました。

于 2014-12-14T01:07:03.143 に答える