2009-10-18 2 views
2

컬렉션을 IList<T> 형식으로 나타내는 개체 모델에 json을 deserialize하려고합니다. IList <T> 컬렉션을 렌더링하는 Json 디시리얼라이저는 무엇입니까?

실제 역 직렬화

은 여기에 있습니다 :

JavaScriptSerializer serializer = new JavaScriptSerializer(); 

return serializer.Deserialize<IList<Contact>>(
    (new StreamReader(General.GetEmbeddedFile("Contacts.json")).ReadToEnd())); 

나는 당신이 암시 적 변환이 무엇인지 알아야지고있어 예외를 게시하기 전에. 이것은 Contact 유형 :

public class Contact 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    public LazyList<ContactDetail> Details { get; set; } 
    //public List<ContactDetail> Details { get; set; } 
} 

그리고 이것은 ContactDetail 유형 :

public class ContactDetail 
{ 
    public int ID { get; set; } 
    public int OrderIndex { get; set; } 
    public string Name { get; set; } 
    public string Value { get; set; } 
} 

LazyList<T>으로 알 수있는 중요한 것은 그것을 구현하는 것입니다 IList<T> :

public class LazyList<T> : IList<T> 
{ 
    private IQueryable<T> _query = null; 
    private IList<T> _inner = null; 
    private int? _iqueryableCountCache = null; 


    public LazyList() 
    { 
     this._inner = new List<T>(); 
    } 

    public LazyList(IList<T> inner) 
    { 
     this._inner = inner; 
    } 

    public LazyList(IQueryable<T> query) 
    { 
     if (query == null) 
      throw new ArgumentNullException(); 
     this._query = query; 
    } 

지금이 LazyList<T> 클래스 정의는 Json을 deserialize 할 때까지 괜찮 았습니다. System.Web.Script.Serialization.JavaScriptSerializerList<T>에 목록을 직렬화하려는 것으로 보이지만 나이가 어림쩡하지만 그 숫자가 IList<T>이어야하므로 내 LazyList<T>으로 캐스팅됩니다 (적어도 내가 잘못 생각한다고 생각합니다).

System.ArgumentException: Object of type 'System.Collections.Generic.List`1[ContactDetail]' cannot be converted to type 'LazyList`1[ContactDetail]'.. 

(위 주석 볼 수 있듯이) 난 내 Contact 유형에 List<ContactDetail>를 사용하여 시도가 작동하는 것 같다 :

나는이 예외를 얻을. 하지만 나는 List<T>을 사용하고 싶지 않습니다. 심지어 List<T>에서 내 LazyList<T>을 상속 받고있는 것처럼 보였지만 List<T>의 내부 T[]을 내 구현에 전달하는 것은 악몽이었으며 내 모델의 어느 곳에서든지 List<T>의 부 풀리를 원하지 않았습니다.

other json 라이브러리도 사용하지 않았을 가능성이 있습니다 (잠재력을 최대한 발휘하지 못했을 가능성이 있습니다.)이 질문의 맨 위에 인용 된 코드를 반복하거나 대체하려고 시도했습니다. 아마도 지나가는 것일 수 있습니다. 설정 매개 변수가 도움이 될 것입니다 ??).

나는 지금 무엇을 시도해야할지 모른다. 다른 디시리얼라이저와 함께 가야합니까? 난 deserializing 자체를 조정할 수 있습니까? 디시리얼라이저를 기쁘게하기 위해 내 유형을 변경해야합니까? 암시 적 캐스팅에 대해 더 걱정하거나 다른 인터페이스를 구현해야합니까?

답변

0

사용자 매핑을위한 linq 지원 기능이 좋은 Json.NET lib을 사용했습니다. 이것은 내 비 직렬화가 다음과 같이 끝난 것입니다.

 JArray json = JArray.Parse(
      (new StreamReader(General.GetEmbeddedFile("Contacts.json")).ReadToEnd())); 

     IList<Contact> tempContacts = (from c in json 
             select new Contact 
             { 
              ID = (int)c["ID"], 
              Name = (string)c["Name"], 
              Details = new LazyList<ContactDetail>(
               (
                from cd in c["Details"] 
                select new ContactDetail 
                { 
                 ID = (int)cd["ID"], 
                 OrderIndex = (int)cd["OrderIndex"], 
                 Name = (string)cd["Name"], 
                 Value = (string)cd["Value"] 
                } 
               ).AsQueryable()), 
              Updated = (DateTime)c["Updated"] 
             }).ToList<Contact>(); 

     return tempContacts; 
0

인터페이스는 단순히 계약 일 뿐이므로 인터페이스로 직접 deserialize 할 수는 없습니다. JavaScriptSerializer는 IList <T>을 구현하는 특정 유형으로 deserialize해야하며 가장 논리적 인 선택은 List <T>입니다. 당신은 쉽게 충분해야합니다, 당신이 게시 코드를 주어진 LazyList에 목록을 변환해야합니다 :

불행하게도 디시리얼라이저가 알 수있는 방법이 없기 때문에 당신은 아마 당신의 클래스를 수정해야합니다
var list = serializer.Deserialize<IList<Contact>>(...); 
var lazyList = new LazyList(list); 
+1

나는 아래쪽의 코드 예제까지 당신이 말한 것을 대부분 얻었습니다. 그 샘플의 첫 번째 줄에 당신이 실패 할 것이라고 게시했습니다. LazyList 클래스에 변경을 제안하면 실패하지 않을 것입니다. –

0

List는 IList의 구현이기 때문에 유형 IList이어야합니다.

디시리얼라이저의 http://json.org에는 소스가 있으므로 하나를 원하는대로 바꿀 수 있습니다.

+0

"수업 수정"이란 무엇을 의미합니까? 더 자세하게 얘기해 주 시겠어요? 수업 또는 디시리얼라이저 소스를 수정해야합니까? ..아니면 둘다? –

+0

LazySerializer 용 ILIst가 아닌 확장 목록. serializer의 소스를 만드는 것보다 더 좋은 옵션이 될 수 있지만, 소스를 변경할 수 없다면 변경할 다른 것을 찾아야합니다. –

관련 문제