2017-12-21 11 views
0

私は、学生レコードシステムと財務システムの間でデータを統合するプログラムを作成しています。 SRSはクラウドベースのソリューションであり、Financeシステムはオンサイトです。データは、RESTful APIを使用してSRSから抽出されます。私は、財務システムとの統合のために返されたリソースをステージングデータベースに書き込む予定です。少しの研究の後、RestSharpを私のソリューションの基盤として使うことに決めました。汎用オブジェクトへのRESTリソースの逆シリアル化

Recommended Usageガイドの後に、私はリクエストを成功させ、レスポンスデータを自分のクラスにデシリアライズする解決策を得ることができました。しかし、私は小さなスピードバンプをヒットし、再び行くために少しの助けが必要です。

SRS Rest APIには、PostalAddressOccupancyリソースが含まれています。

enter image description here

私の問題は、乗員の特性である:SRSのAPIドキュメントによれば、以下の構造を有しています。これは、混合型で示されるように、他の多くのリソースタイプ(つまり、学生、スタッフ、Guardianなど)のいずれか1つになります。

これは、ジェネリックを使用してデータモデルで簡単に表現できます。例えば

public class PostalAddressOccupancy<T> 
{ 
    public DateTime EffectiveDate { get; set; } 
    public DateTime EndDate { get; set; } 
    public string EntityType { get; set; } 
    public string Href { get; set; } 
    public string Id { get; set; } 
    public bool IsCorrespondenceAddress { get; set; } 
    public T Occupant { get; set; } 
    public PostalAddress PostalAddress { get; set; } 
    public string PostalAddressType { get; set; } 

    public static PostalAddressOccupancy<T> GetPostalAddressOccupancy(string id) 
    { 
     var request = new RestRequest 
     { 
      Resource = "PostalAddressOccupancy/{Id}", 
      RootElement = "postalAddressOccupancy" 
     }; 

     request.AddParameter("Id", id, ParameterType.UrlSegment); 

     RestApiClient restApiClient = new RestApiClient("SRS API"); 
     return restApiClient.Execute<PostalAddressOccupancy<T>>(request); 
    } 

    public static List<PostalAddressOccupancy<T>> GetPostalAddressOccupancies() 
    { 
     List<PostalAddressOccupancy<T>> list = new List<PostalAddressOccupancy<T>>(); 

     var request = new RestRequest 
     { 
      Resource = "PostalAddressOccupancy", 
      RootElement = "postalAddressOccupancies" 
     }; 

     RestApiClient restApiClient = new RestApiClient("SRS API"); 

     foreach (var pao in restApiClient.Execute<List<PostalAddressOccupancy<T>>>(request)) 
     { 
      list.Add(GetPostalAddressOccupancy(pao.Href.Split('/').Last())); 
     } 

     return list; 
    } 
} 

私の問題はRestSharpが正しく乗員のタイプは応答データに戻されているかを理解するために取得する方法です。上記のGetPostalAddressOccupanciesメソッドを使用して、すべてのものが乗員から正しく非直列化されたオブジェクトのリストを取得します。これは、そのプロパティがキーと値のペアとして含まれている基本オブジェクト型として返されます。

RestSharpデシリアライザのヒントを提供するために、クラスまたはジェネリックプロパティをいくつかのタグで飾る必要がありますか?

また、リソースに基本プロパティ(entityTypeなど)が含まれていることに気付きました。したがって、これを介して乗員の種類を識別することができますが、どのように役立つかもしれないのか分かりません。

+0

「RestApiClient」とは何ですか?それは[restsharp](https://github.com/restsharp/RestSharp/search?utf8=%E2%9C%93&q=RestApiClient&type=)の一部ではないようです。 – dbc

答えて

0

RestSharpはJSONのシリアル化にSimpleJsonを使用しています。 Json.NETとは異なり、このシリアライザには、多態的なプロパティの逆シリアル化、カスタムコンバータまたは代理置換のビルトインサポートがありません。

したがって、応答を中間オブジェクト、具体的にはJsonObjectに解析し、存在するプロパティに基づいて占有者のタイプを識別し、最終的なタイプにデシリアライズします。

まず、とても似PostalAddressOccupancy<T>ための非汎用の基本クラスを抽出するためにはるかに容易になるだろう:

public class Student 
{ 
    public string Name { get; set; } 
    public string StudentId { get; set; } 
} 

public class Staff 
{ 
    public string Name { get; set; } 
    public string StaffId { get; set; } 
} 

public abstract class PostalAddressOccupancy 
{ 
    public DateTime EffectiveDate { get; set; } 
    public DateTime EndDate { get; set; } 
    public string EntityType { get; set; } 
    public string Href { get; set; } 
    public string Id { get; set; } 
    public bool IsCorrespondenceAddress { get; set; } 
    public PostalAddress PostalAddress { get; set; } 
    public string PostalAddressType { get; set; } 

    public abstract object GetOccupant(); 
} 

public class PostalAddressOccupancy<T> : PostalAddressOccupancy 
{ 
    public T Occupant { get; set; } 

    public override object GetOccupant() 
    { 
     return Occupant; 
    } 
} 

public class PostalAddress 
{ 
    // Or whatever. Type was not included in the question. 
    public string Address { get; set; } 
} 

は今、あなたを含む乗員、さまざまな種類のを持っている想像次にIRestResponseを与えられたPostalAddressOccupancy<T>に逆シリアル化することができます。ここで、TStudentまたはStaffになります。プロパティnam非ジェネリックベース型を有する戻り署名がobject以外のものであってもよいことを意味する

using SimpleJson; 
using RestSharp; 

public static class PostalAddressOccupancyExtensions 
{ 
    public static PostalAddressOccupancy DeserializePostalAddressOccupancy(this RestSharp.IRestResponse response) 
    { 
     var addressObj = (JsonObject)SimpleJson.SimpleJson.DeserializeObject(response.Content); 
     var type = PostalAddressOccupancyExtensions.InferPostalAddressOccupancyType(addressObj); 
     return (PostalAddressOccupancy)SimpleJson.SimpleJson.DeserializeObject(response.Content, type); 
    } 

    static Type InferPostalAddressOccupancyType(JsonObject root) 
    { 
     var occupantObj = root["Occupant"]; 
     if (occupantObj is JsonObject) 
     { 
      var occupant = (JsonObject)occupantObj; 
      // Add logic to recognize other cases as required. 
      if (occupant.ContainsKey("StudentId")) 
      { 
       return typeof(PostalAddressOccupancy<Student>); 
      } 
      else if (occupant.ContainsKey("StaffId")) 
      { 
       return typeof(PostalAddressOccupancy<Staff>); 
      } 
     } 
     // Or throw an exception, if you prefer. 
     return typeof(PostalAddressOccupancy<>).MakeGenericType(new[] { occupantObj.GetType() }); 
    } 
} 

は注意:実際にJSONに存在し、適切な最終の種類を選択ES。サンプル作業.Net fiddle

を使用する場合は、追加オプションがあります。例えば。あなたは可能性:

+1

ありがとうございます。次の日にそれを試してみたり –

関連する問題