source

C# JSON의 자동 속성 역직렬화

nicesource 2023. 2. 23. 22:55
반응형

C# JSON의 자동 속성 역직렬화

JSON에 표시되는 JavaScript 오브젝트를 적절한 C# 클래스로 역직렬화해야 합니다.자동 속성의 훌륭한 특징들을 고려하면, 나는 단지 필드를 갖는 것보다 이러한 클래스들에 그것들을 두는 것을 선호한다.아쉽게도.NET 시리얼라이제이션엔진(적어도 디폴트로는)은 시리얼라이제이션 시 자동 속성을 완전히 무시하고 JavaScript 오브젝트에는 없는 백업필드만 신경씁니다.

backing 필드에 이름을 붙이는 표준 방법이 없기 때문에 솔직히 말하자면 "C# backing fields를 가진 것처럼 보이는 JavaScript 객체를 작성하자"는 접근 방식은 다소 지저분하게 들리므로 번거롭게 하고 싶지 않습니다.시리얼라이제이션엔진을 강제로 기동할 수 있다면 JavaScript 필드를 C# auto-properties로 시리얼화할 수 있는 유일한 방법입니다.또는 백업 필드를 사용하여 직접 자산을 사용합니다.유감스럽게도, 저는 이 작업이 어떻게 이루어졌는지, 그리고 이 작업이 가능한지 전혀 알 수 없습니다.어떤 아이디어라도 주시면 감사하겠습니다.

편집: 예를 다음에 나타냅니다.

Javascript:

function Cat()
{
    this.Name = "Whiskers";
    this.Breed = "Tabby";
}
var cat = new Cat();

그런 다음 "{Name: 'Whiskers'}"로 일련화됩니다.

C# 클래스:

[Serializable()]
public class Cat
{
    public string Name { get; set; }
    public string Breed { get; set; }
}

디시리얼라이제이션코드는 실패입니다.

new DataContractJsonSerializer(typeof(Cat)).ReadObject(inputStream);

또한 예외로 보아 backing 필드를 찾고 있기 때문에 오류가 발생하는 것이 분명합니다.

EDIT2: 이것이 도움이 되는 경우는, 다음과 같은 예외가 있습니다(내부 예외는 다음과 같습니다.

System.실행시간시리얼화시리얼화예외.

"데이터 계약 유형 '테스트'입니다.필요한 데이터 멤버 '' 때문에 Cat'을(를) 역직렬화할 수 없습니다.<Name>k__BackingField, <Breed>k__BackingField를 찾을 수 없습니다."

여기서 일어나고 있는 것은 디시리얼라이저가 배경 필드의 이름을 추측하려고 하고 있다는 것입니다.다음과 같이 명시적 매핑(DataContract/DataMember 속성)을 추가하면 이 문제를 해결할 수 있습니다.

[DataContract]
public class Cat
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Breed { get; set; }
}

다음과 같이 할 수 있습니다.JavaScriptSerializer에서 발견되다System.Web.Script.Serialization네임스페이스:

JavaScriptSerializer serializer = new JavaScriptSerializer();
Cat c = serializer.Deserialize<Cat>(jsonString);

자동 속성을 가진 POCO 오브젝트를 가지고 있는데, 이것은 정상적으로 동작합니다.

편집: JSON Serializer에 대한 내용은 에 기재되어 있습니다. 시리얼라이저와 비교하다NETDataContractJsonSerializer.

baretta의 답변으로 k__Backing Field의 부풀어 오른 부분이 해결되었습니다.비슷한 방법으로 XML 또는 JSON으로 자동 직렬화되도록 이 클래스를 꾸밀 수 있는 작은 부록입니다.

[Serializable, XmlRoot, DataContract]
public class Cat
{
  [XmlElement]
  [DataMember]
  public string Name { get; set; }
  [XmlElement]
  [DataMember]
  public string Breed { get; set; }
}

그런 다음 DataContractJsonSerializer 또는 XmlSerializer를 사용하여 엔드포인트를 준비합니다.

웹 서비스를 통해 데이터를 전달하고 있을 겁니다.Web Service 클래스를 ScriptMethod Atribute uncommented-out과 함께 사용하는 경우 웹 서비스 메서드는 기본적으로 JSON을 읽을 수 있습니다.위에서 언급한 것과 동일한 JavaScriptSerializer를 사용합니다.만약 당신이 WCF를 사용한다면 나는 논리에 조금 더 모호합니다.

그러나 JSON 개체가 클래스의 모든 속성에 대한 데이터를 반환하는지 확인하십시오.오류로 인해 예제에 없는 Breed 속성에 대한 언급이 있습니다.

또한 JavaScript 측에서는 JavaScript의 동적 특성에 따라 새로운 속성을 객체에 쉽게 추가할 수 있습니다.이로 인해 순환 참조가 발생할 수 있습니다.추가했을 가능성이 있는 데이터는 모두 삭제해야 합니다(Web 메서드를 사용하여 데이터를 송신하는 경우와 마찬가지로 삭제한 후 다시 추가해야 합니다).

언급URL : https://stackoverflow.com/questions/945585/c-sharp-automatic-property-deserialization-of-json

반응형