2017-12-21 44 views
0

저는 Student Record System과 Finance System간에 데이터를 통합하는 프로그램을 작성하고 있습니다. SRS는 클라우드 기반 솔루션이며 재무 시스템은 온 프레미엄입니다. 데이터는 RESTful API를 사용하여 SRS에서 추출됩니다. 그런 다음 재무 시스템과의 통합을 위해 반환 된 자원을 준비 데이터베이스에 기록 할 계획입니다. 약간의 연구 끝에 RestSharp를 내 솔루션의 기반으로 사용하기로 결정했습니다.REST 리소스를 일반 객체로 deserializing

Recommended Usage 가이드에 이어 성공적으로 요청을 만들고 솔루션 클래스에 응답 데이터를 deserialize하는 솔루션을 얻을 수있었습니다. 그러나 나는 작은 스피드 범프를 치고 다시 갈 수 있도록 약간의 도움이 필요하다.

SRS Rest API에는 PostalAddressOccupancy 자원이 포함되어 있습니다.

enter image description here

내 문제는 탑승자 속성입니다 : SRS를 API 문서에 따르면 그것은 다음과 같은 구조를 가지고있다. 혼합 된 유형으로 표시되는이 번호는 다른 여러 자원 유형 (예 : 학생, 직원, 보호자 등) 중 하나 일 수 있습니다.

제네릭을 사용하여 데이터 모델에서이를 쉽게 나타낼 수 있습니다. 예 :

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 메서드를 사용하면 모든 항목이 올바르게 점유되어있는 상태에서 deserialized 된 개체 목록을 얻습니다. 이것은 키/값 쌍으로 포함 된 속성을 가진 기본 객체 유형으로 반환됩니다.

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과는 달리이 serializer에는 다형성 속성 비 직렬화, 사용자 지정 변환기 또는 대체 대체가 기본적으로 지원되지 않습니다.

따라서 중간 객체 (구체적으로 JsonObject)로 응답을 구문 분석 한 다음 현재 속성을 기반으로 점유자 유형을 식별 한 다음 마지막 유형으로 deserialize해야합니다.

첫째,과 같이 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 json으로 실제로 존재 ES 및 해당 최종 유형 선택 : 비 일반적인 기본 유형을 갖는 반환 서명이 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() }); 
    } 
} 

공지 사항. 샘플 작업 .Net fiddle.

을 기꺼이 사용하려는 경우 추가 옵션이 있습니다. 예 : 당신은 할 수 :

+1

감사합니다. 다음날에 시험해 보겠습니다. –