비고
이 글은 DataContractJsonSerializer에 관한 것입니다. JSON 직렬화 및 역직렬화를 포함하는 대부분의 시나리오에서는 System.Text.Json 네임스페이스의 API를 사용하는 것이 좋습니다.
JSON(JavaScript 개체 표기법)은 브라우저 내의 웹 페이지에서 실행되는 JavaScript 코드에서 사용하도록 특별히 설계된 데이터 형식입니다. WCF(Windows Communication Foundation)에서 만든 ASP.NET AJAX 서비스에서 사용하는 기본 데이터 형식입니다.
이 형식은 ASP.NET 통합하지 않고 AJAX 서비스를 만들 때도 사용할 수 있습니다. 이 경우 XML이 기본값이지만 JSON을 선택할 수 있습니다.
마지막으로 JSON 지원이 필요하지만 AJAX 서비스를 DataContractJsonSerializer 만들지 않는 경우 .NET 개체를 JSON 데이터로 직접 직렬화하고 이러한 데이터를 .NET 형식의 인스턴스로 다시 역직렬화할 수 있습니다. 이 작업을 수행하는 방법에 대한 설명은 방법: JSON 데이터 직렬화 및 역직렬화를 참조하세요.
JSON으로 작업할 때는 DataContractSerializer이(가) 지원하는 것과 동일한 .NET 형식이 몇 가지 예외를 제외하고 지원됩니다. 지원되는 형식 목록은 데이터 계약 직렬 변환기에서 지원하는 형식을 참조하세요. 여기에는 대부분의 기본 형식, 대부분의 배열 및 컬렉션 형식, 그리고 DataContractAttribute와 DataMemberAttribute를 사용하는 복합 형식이 포함됩니다.
JSON 형식에 .NET 형식 매핑
다음 표에서는 serialization 및 deserialization 프로시저에 의해 매핑되는 경우 .NET 형식과 JSON/JavaScript 형식 간의 대응을 보여 줍니다.
| .NET 형식 | JSON/JavaScript | 비고 |
|---|---|---|
| 모든 숫자 형식(예Int32: DecimalDouble | 숫자 | 와 같은 Double.NaNDouble.PositiveInfinityDouble.NegativeInfinity 특수 값은 지원되지 않으며 잘못된 JSON이 발생합니다. |
| Enum | 숫자 | 이 문서의 뒷부분에 있는 "열거형 및 JSON"을 참조하세요. |
| Boolean | 불리언 (Boolean) | |
| String, Char | 문자열 | |
| TimeSpan, , GuidUri | 문자열 | JSON에서 이러한 형식의 형식은 XML과 동일합니다(기본적으로 ISO 8601 기간 형식의 시간 범위, "12345678-ABCD-ABCD-1234567890AB" 형식의 GUID 및 자연 문자열 형식의 URI(예: "http://www.example.com"). 자세한 내용은 데이터 계약 스키마 참조를 참조하세요. |
| XmlQualifiedName | 문자열 | 형식은 "name:namespace"입니다(첫 번째 콜론 앞의 모든 항목은 이름임). 이름 또는 네임스페이스가 누락될 수 있습니다. 네임스페이스가 없는 경우 콜론도 생략할 수 있습니다. |
Command(System.Windows.Input.ICommand 형식) |
숫자 배열 | 각 숫자는 1 바이트의 값을 나타냅니다. |
| DateTime | DateTime 또는 String | 이 문서의 뒷부분에 있는 날짜/시간 및 JSON을 참조하세요. |
| DateTimeOffset | 복합 형식 | 이 문서의 뒷부분에 있는 날짜/시간 및 JSON을 참조하세요. |
| XML 및 ADO.NET 형식(XmlElement, XElement; XmlNode의 배열 ISerializable; DataSet)". |
문자열 | 이 문서의 XML 형식 및 JSON 섹션을 참조하세요. |
| DBNull | 빈 복합 형식 | -- |
| 컬렉션, 사전 및 배열 | 배열 | 이 항목의 컬렉션, 사전 및 배열 섹션을 참조하세요. |
| 복합 유형(DataContractAttribute 적용 또는 SerializableAttribute) | 복합 형식 | 데이터 멤버는 JavaScript 복합 형식의 멤버가 됩니다. |
| 인터페이스 ISerializable를 구현하는 복합 형식 | 복합 형식 | 다른 복합 형식과 동일하지만 일부 ISerializable 형식은 지원되지 않습니다. ISerializable 지원을 참조하세요. |
Null 모든 형식에 대한 값 |
없음 | Nullable 값 형식도 지원되며 Null을 허용하지 않는 값 형식과 동일한 방식으로 JSON에 매핑됩니다. |
열거형 및 JSON
열거형 멤버 값은 JSON에서 숫자로 처리됩니다. 이는 데이터 계약에서 처리되는 방식과 다르며 멤버 이름으로 포함됩니다. 데이터 계약 처리에 대한 자세한 내용은 데이터 계약의 열거형 형식을 참조하세요.
예를 들어,
public enum Color {red, green, blue, yellow, pink}가 있는 경우,yellow를 직렬화하면 문자열 "yellow"가 아닌 숫자 3이 생성됩니다.모든
enum멤버는 직렬화할 수 있습니다. EnumMemberAttribute 및 NonSerializedAttribute 특성은 사용되는 경우 무시됩니다.존재하지
enum않는 값을 역직렬화할 수 있습니다. 예를 들어 해당 색 이름이 정의되어 있지 않더라도 값 87을 이전 Color 열거형으로 역직렬화할 수 있습니다.플래그
enum는 특수하지 않으며 다른enum플래그와 동일하게 처리됩니다.
날짜/시간 및 JSON
JSON 형식은 날짜 및 시간을 직접 지원하지 않습니다. 그러나 이러한 형식은 매우 일반적으로 사용되며 ASP.NET AJAX는 이러한 형식에 대해 특별한 지원을 제공합니다. ASP.NET AJAX 프록시를 사용하는 경우 .NET의 DateTime 형식은 JavaScript의 형식에 DateTime 완전히 해당합니다.
ASP.NET을 사용하지 않는 경우, DateTime 유형은 JSON에서 이 항목의 고급 정보 섹션에 설명된 특수 형식의 문자열로 표현됩니다.
DateTimeOffset 는 JSON에서 복합 형식으로 표시됩니다. {"DateTime":d ateTime,"OffsetMinutes":offsetMinutes}.
offsetMinutes멤버는 그리니치 평균시(GMT) 또는 현재 협정 세계시(UTC)로 불리는 시간대를 기준으로 한 현지 시간 오프셋으로, 관심 있는 이벤트의 위치와 관련이 있습니다. 멤버는dateTime관심 있는 이벤트가 발생한 시점을 나타내는 인스턴스를 의미합니다(ASP.NET AJAX가 사용 중일 때는 JavaScript의DateTime가 되고, 그렇지 않은 경우 문자열이 됩니다). serialization의 경우,dateTime멤버는 항상 GMT로 직렬화됩니다. 따라서 오전 3:00 뉴욕 시간을dateTime설명하는 경우 시간 구성 요소는 오전 8:00이고offsetMinutes300(GMT에서 300분 또는 5시간을 뺀 시간)입니다.비고
DateTime 및 DateTimeOffset 개체는 JSON으로 직렬화될 때 정보만 밀리초 정밀도로 유지합니다. serialization 중에 밀리초 미만 값(마이크로/나노초)이 손실됩니다.
XML 형식 및 JSON
XML 형식은 JSON 문자열이 됩니다.
예를 들어 XElement 형식의 데이터 멤버 "q"에 abc/<가 포함된 >경우 JSON은 {"q":"<abc/>"}입니다.
XML 래핑 방법을 지정하는 몇 가지 특수 규칙이 있습니다. 자세한 내용은 이 문서의 뒷부분에 있는 고급 정보 섹션을 참조하세요.
ASP.NET AJAX를 사용 중이며 JavaScript에서 문자열을 사용하지 않고 대신 XML DOM을 사용하려는 경우 속성을 XML로 ResponseFormat 설정하거나 WebGetAttribute 속성을 XML로 ResponseFormat설정합니다WebInvokeAttribute.
컬렉션, 사전 및 배열
모든 컬렉션, 사전 및 배열은 JSON에서 배열로 표시됩니다.
이를 사용하는 CollectionDataContractAttribute 모든 사용자 지정은 JSON 표현에서 무시됩니다.
사전은 JSON으로 직접 작업하는 방법이 아닙니다. <사전 문자열, 개체>는 다른 JSON 기술 작업에서 예상한 것과 동일한 방식으로 WCF에서 지원되지 않을 수 있습니다. 예를 들어 "abc"가 "xyz"에 매핑되고 "def"가 사전에서 42로 매핑되는 경우 JSON 표현은 {"abc":"xyz","def":42}이 아니라 [{"Key":"abc","Value":"xyz"},{"Key":"def","Value":42}]입니다.
JSON을 직접 사용하려는 경우(엄격한 계약을 미리 정의하지 않고 동적으로 키 및 값에 액세스) 다음과 같은 몇 가지 옵션이 있습니다.
약한 형식의 AJAX(JSON Serialization) 샘플을 사용하는 것이 좋습니다.
인터페이스 및 역직렬화 생성자를 사용하는 ISerializable 것이 좋습니다. 이러한 두 메커니즘을 사용하면 직렬화 및 역직렬화 시 JSON 키/값 쌍에 각각 액세스할 수 있지만 부분 신뢰 시나리오에서는 작동하지 않습니다.
serializer를 사용하는 대신 JSON과 XML 간의 매핑 을 사용하는 것이 좋습니다.
serialization 컨텍스트의 다형성은 기본 형식이 예상되는 곳에서 파생 형식을 serialize할 수 있는 기능을 나타냅니다. 컬렉션을 다형적으로 사용하는 경우, 예를 들어 컬렉션을 Object에 할당할 때, 특별한 JSON 전용 규칙이 있습니다. 이 문제는 이 문서의 뒷부분에 있는 고급 정보 섹션에서 자세히 설명합니다.
추가 정보
데이터 멤버 순서
JSON을 사용하는 경우 데이터 멤버의 순서는 중요하지 않습니다. 특히, 설정된 경우에도 Order JSON 데이터는 어떤 순서로든 역직렬화할 수 있습니다.
JSON 형식
JSON 형식은 역직렬화에서 이전 테이블과 일치할 필요가 없습니다. 예를 들어 Int 일반적으로 JSON 번호에 매핑되지만 해당 문자열에 유효한 숫자가 포함되어 있는 한 JSON 문자열에서 역직렬화할 수도 있습니다. 즉, "q"라는 데이터 멤버가 있는 Int 경우 {"q":42} 및 {"q":"42"} 모두 유효합니다.
다형성
다형 직렬화는 기본 유형이 예상되는 곳에서 파생 유형을 직렬화할 수 있는 기능을 포함합니다. 이는 XML serialization이 지원되는 방식과 비슷한 WCF의 JSON serialization에 대해 지원됩니다. 예를 들어 MyDerivedType가 예상되는 경우 MyBaseType를 직렬화하거나 Int가 예상되는 경우 Object를 직렬화할 수 있습니다.
복합 형식을 역직렬화하지 않는 한 기본 형식이 필요한 경우 파생 형식을 역직렬화할 때 형식 정보가 손실될 수 있습니다. 예를 들어, Uri가 예상되는 위치에 Object이(가) 직렬화되면 JSON 문자열이 생성됩니다. 이 문자열이 역 Object직렬화되면 .NET String 이 반환됩니다. 역직렬 변환기는 문자열이 처음에 형식 Uri이었다는 것을 알지 못합니다. 일반적으로 Object을 예상할 때, 모든 JSON 문자열은 .NET 문자열로 역직렬화되며, .NET 컬렉션, 사전 및 배열과 같은 것을 직렬화하는 데 사용되는 모든 JSON 배열은 실제 원래 형식에 관계없이 .NET Array의 형태로 Object으로 역직렬화됩니다. JSON의 불리언은 .NET의 Boolean로 매핑됩니다. 예상되는 Object가 있을 때, JSON 숫자는 .NET의 Int32, Decimal 또는 Double 중 가장 적절한 형식으로 자동으로 선택되어 역직렬화됩니다.
인터페이스 형식으로 역직렬화하면 선언된 형식 DataContractJsonSerializer 이 개체인 것처럼 역직렬화됩니다.
사용자 고유의 기본 및 파생 형식으로 작업하는 경우 일반적으로 KnownTypeAttribute 또는 ServiceKnownTypeAttribute와 같은 메커니즘을 사용해야 합니다. 예를 들어, 반환 값이 Animal인 연산이 실제로 Cat에서 파생된 Animal 인스턴스를 반환하는 경우, KnownTypeAttribute 형식이나 Animal 작업에 ServiceKnownTypeAttribute를 적용하고 이러한 특성에 Cat 형식을 지정해야 합니다. 자세한 내용은 데이터 계약 알려진 형식을 참조하세요.
다형 직렬화의 작동 방식과 이를 사용할 때 고려해야 하는 몇 가지 제한 사항에 대한 자세한 내용은 이 문서의 뒷부분에 있는 고급 정보 섹션을 참조하세요.
버전 관리
인터페이스를 포함한 IExtensibleDataObject 데이터 계약 버전 관리 기능은 JSON에서 완전히 지원됩니다. 또한 대부분의 경우, 한 형식(예: XML)으로 형식을 역직렬화한 다음, 다른 형식(예: JSON)으로 직렬화하여 IExtensibleDataObject 내부의 데이터를 그대로 유지할 수 있습니다. 자세한 내용은 Forward-Compatible 데이터 계약을 참조하세요. JSON은 순서가 없는 형식이므로, 순서 정보가 손실될 수 있습니다. 또한 JSON은 동일한 키 이름을 가진 여러 키/값 쌍을 지원하지 않습니다. 마지막으로, 모든 연산 IExtensibleDataObject 은 본질적으로 다형입니다. 즉, 파생된 형식이 모든 형식의 기본 형식에 할당 Object됩니다.
URL의 JSON
HTTP GET 동사와 함께 ASP.NET AJAX 엔드포인트를 사용하는 경우(특성 사용 WebGetAttribute ) 들어오는 매개 변수는 메시지 본문 대신 요청 URL에 표시됩니다. JSON은 요청 URL에서도 지원되므로, 'number'라는 이름의 Int와 'p'라는 복합 형식을 사용하는 작업이 있을 경우, URL은 다음과 같이 Person 유사할 수 있습니다.
http://example.com/myservice.svc/MyOperation?number=7&p={"name":"John","age":42}
ASP.NET AJAX 스크립트 관리자 컨트롤 및 프록시를 사용하여 서비스를 호출하는 경우 이 URL은 프록시에 의해 자동으로 생성되며 표시되지 않습니다. JSON은 NON-ASP.NET AJAX 엔드포인트의 URL에서 사용할 수 없습니다.
고급 정보
ISerializable 지원
지원되는 형식 및 지원되지 않는 ISerializable 형식
일반적으로 인터페이스를 구현 ISerializable 하는 형식은 JSON을 직렬화/역직렬화할 때 완전히 지원됩니다. 그러나 이러한 형식 중 일부(일부 .NET Framework 형식 포함)는 JSON별 serialization 측면으로 인해 올바르게 역직렬화되지 않도록 구현됩니다.
이 ISerializable경우 개별 데이터 멤버의 형식을 미리 알 수 없습니다. 이렇게 하면 형식을 개체로 역직렬화하는 것과 유사한 다형적 상황이 발생합니다. 앞에서 설명한 대로 JSON에서 형식 정보가 손실될 수 있습니다. 예를 들어
enum을 ISerializable 구현에서 직렬화하고, 적절한 캐스트 없이 직접enum으로 역직렬화하려고 하면 실패합니다.enum은 JSON에서 숫자를 사용하여 직렬화되며, JSON 숫자는 Int32, Decimal 또는 Double 같은 .NET 기본 제공 숫자 형식으로 역직렬화되기 때문입니다. 따라서 값으로 사용된enum숫자가 손실됩니다.ISerializable 유형은 역직렬화 생성자에서 특정 순서의 역직렬화에 의존하는 형식일 경우, 일부 JSON 데이터를 역직렬화하지 못할 수도 있습니다. 대부분의 JSON 직렬 변환기가 특정 순서를 보장하지 않기 때문입니다.
팩터리 형식
IObjectReference 인터페이스는 일반적으로 JSON에서 지원되지만 "팩터리 형식" 기능이 필요한 형식(인터페이스를 구현하는 형식과 다른 형식 GetRealObject(StreamingContext) 의 인스턴스 반환)은 지원되지 않습니다.
DateTime Wire 형식
DateTime 값은 "/Date(700000+0500)/"의 형식으로 JSON 문자열로 나타납니다. 여기서 첫 번째 숫자(제공된 예제의 경우 700000)는 GMT 표준 시간대의 시간(밀리초)이며, 1970년 1월 1일 자정 이후의 일반(일광 절약 시간)입니다. 숫자는 이전 시간을 나타내는 음수일 수 있습니다. 예제에서 "+0500"으로 구성된 부분은 선택 사항이며 시간이 Local 종류임을 나타냅니다. 즉, 역직렬화 시 현지 표준 시간대로 변환되어야 합니다. 시간이 없으면 시간은 Utc로 역직렬화됩니다. 실제 숫자(이 예제에서는 "0500") 및 해당 기호(+ 또는 -)는 무시됩니다.
Serialize할 때 DateTime, Local 및 Unspecified 시간은 오프셋과 함께 기록되고, Utc는 오프셋 없이 기록됩니다.
ASP.NET AJAX 클라이언트 JavaScript 코드는 이러한 문자열을 JavaScript DateTime 인스턴스로 자동으로 변환합니다. .NET에서 형식 DateTime 이 아닌 유사한 형식을 가진 다른 문자열도 변환됩니다.
변환은 "/" 문자가 이스케이프되는 경우에만 발생합니다(즉, JSON은 "\/Date(700000+0500)\/"처럼 표시됨). 따라서 WCF의 JSON 인코더(사용 WebHttpBinding)는 항상 "/" 문자를 이스케이프합니다.
JSON 문자열의 XML
XmlElement
XmlElement 는 래핑 없이 있는 그대로 직렬화됩니다. 예를 들어 abc/XmlElement를 포함하는 <형식 > 의 데이터 멤버 "x"는 다음과 같이 표시됩니다.
{"x":"<abc/>"}
XmlNode 배열
Array 형식의 개체는 형식 XmlNode 에 대한 표준 데이터 계약 네임스페이스의 ArrayOfXmlNode라는 요소에 래핑됩니다. "x"가 "value"와 빈 요소 노드 "M"을 포함하는 네임스페이스 "ns"의 특성 노드 "N"을 포함하는 배열인 경우 표현은 다음과 같습니다.
{"x":"<ArrayOfXmlNode xmlns=\"http://schemas.datacontract.org/2004/07/System.Xml\" a:N=\"value\" xmlns:a=\"ns\"><M/></ArrayOfXmlNode>"}
다른 요소 앞에 있는 XmlNode 배열의 시작 부분에 있는 빈 네임스페이스의 특성은 지원되지 않습니다.
XElement 및 DataSet을 포함한 IXmlSerializable 형식
ISerializable 형식은 "콘텐츠 형식", "DataSet 형식" 및 "요소 형식"으로 세분화됩니다. 이러한 형식의 정의는 데이터 계약의 XML 및 ADO.NET 형식을 참조하세요.
"Content" 및 "DataSet" 형식은 이전 섹션에서 설명한 Array 개체와 유사하게 XmlNode 직렬화됩니다. 해당 형식의 데이터 계약 이름 및 네임스페이스에 맞는 요소 안에 래핑됩니다.
"요소" 형식 XElement 은 이 문서에서 앞에서 설명한 것과 비슷하게 XmlElement 있는 그대로 직렬화됩니다.
다형성
형식 정보 유지
앞에서 설명한 대로 다형성은 JSON에서 지원되며 몇 가지 제한 사항이 있습니다. JavaScript는 약한 형식의 언어이며 형식 ID는 일반적으로 문제가 되지 않습니다. 그러나 JSON을 사용하여 강력한 형식의 시스템(.NET)과 약한 형식의 시스템(JavaScript) 간에 통신하는 경우 형식 ID를 유지하는 것이 유용합니다. 예를 들어 데이터 계약 이름이 "Square" 및 "Circle"인 형식은 데이터 계약 이름이 "Shape"인 형식에서 파생됩니다. "Circle"이 .NET에서 JavaScript로 전송되고 나중에 "Shape"를 예상하는 .NET 메서드로 반환되는 경우 .NET 쪽에서 문제의 개체가 원래 "Circle"임을 아는 것이 유용합니다. 그렇지 않으면 파생 형식과 관련된 정보(예: "Circle"의 "radius" 데이터 멤버)가 손실될 수 있습니다.
형식 ID를 유지하려면 복합 형식을 JSON으로 직렬화할 때 "형식 힌트"를 추가할 수 있으며 역직렬 변환기는 힌트를 인식하고 적절하게 작동합니다. "형식 힌트"는 키 이름이 "__type"인 JSON 키/값 쌍입니다(밑줄 두 개 뒤에 "type"이라는 단어가 붙은). 값은 "DataContractName:DataContractNamespace" 형식의 JSON 문자열입니다(첫 번째 콜론까지의 모든 항목은 이름임). 앞의 예제를 사용하여 "원"을 다음과 같이 직렬화할 수 있습니다.
{"__type":"Circle:http://example.com/myNamespace","x":50,"y":70,"radius":10}
형식 힌트는 XML 스키마 인스턴스 표준에 정의된 xsi:type 특성과 매우 유사하며, XML을 직렬화/역직렬화할 때 사용됩니다.
형식 힌트와 충돌할 가능성이 있으므로 "__type"이라는 데이터 멤버는 사용할 수 없습니다.
형식 힌트 크기 줄이기
JSON 메시지의 크기를 줄이기 위해 기본 데이터 계약 네임스페이스 접두사(http://schemas.datacontract.org/2004/07/)가 "#" 문자로 바뀝니다. 이 대체를 되돌릴 수 있도록 이스케이프 규칙이 사용됩니다. 네임스페이스가 "#" 또는 "\" 문자로 시작하는 경우 추가 "\" 문자가 추가됩니다. 따라서 "Circle"이 .NET 네임스페이스 "MyApp.Shapes"의 형식인 경우 기본 데이터 계약 네임스페이스는 .NET 네임스페이스입니다 http://schemas.datacontract.org/2004/07/MyApp. 셰이프 및 JSON 표현은 다음과 같습니다.
{"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}
잘린 이름(#MyApp.Shapes)과 전체(http://schemas.datacontract.org/2004/07/MyApp.Shapes) 이름은 모두 역직렬화할 때 이해됩니다.
JSON 개체의 형식 힌트 위치
형식 힌트는 JSON 표현에서 먼저 나타나야 합니다. JSON 처리에서 키/값 쌍의 순서가 중요한 유일한 경우입니다. 예를 들어 다음은 형식 힌트를 지정하는 유효한 방법이 아닙니다.
{"x":50,"y":70,"radius":10,"__type":"Circle:#MyApp.Shapes"}
DataContractJsonSerializer WCF 및 ASP.NET AJAX 클라이언트 페이지에서 사용하는 두 가지 모두 항상 먼저 형식 힌트를 내보낸다.
형식 힌트는 복합 형식에만 적용됩니다.
복합 형식이 아닌 형식에 대한 형식 힌트를 내보낸 방법은 없습니다. 예를 들어 작업에 반환 형식이 Object 있지만 원을 반환하는 경우 JSON 표현은 앞부분에서와 같이 표시될 수 있으며 형식 정보는 유지됩니다. 그러나 Uri가 반환되면 JSON 표현은 문자열이며 Uri를 나타내는 데 사용된 문자열이 손실됩니다. 이는 기본 형식뿐만 아니라 컬렉션 및 배열에도 적용됩니다.
형식 힌트가 언제 출력되는지
형식 힌트는 메시지 크기를 크게 늘릴 수 있습니다(이를 완화하는 한 가지 방법은 가능한 경우 더 짧은 데이터 계약 네임스페이스를 사용하는 것입니다). 따라서 다음 규칙은 형식 힌트를 내보내는지 여부를 제어합니다.
ASP.NET AJAX를 사용할 때 기본/파생 할당이 없는 경우에도 가능할 때마다 항상 형식 힌트가 내보내집니다. 예를 들어, 동일한 원이 원에 할당된 경우에도 그렇습니다. (정보 손실 없이 약한 형식의 JSON 환경에서 강력한 형식의 .NET 환경으로 호출하는 프로세스를 완전히 사용하도록 설정하는 데 필요합니다.)
AJAX 서비스를 ASP.NET 통합 없이 사용하는 경우, 형식 힌트는 기본/파생 클래스 간 할당이 있을 때에만 내보내집니다. 즉, Circle이 Shape에 할당될 때는 힌트가 제공되지만, Circle에 할당될 때는 제공되지 않습니다. 이렇게 하면 JavaScript 클라이언트를 올바르게 구현하는 데 필요한 최소 정보를 제공하므로 성능이 향상되지만 잘못 디자인된 클라이언트의 형식 정보 손실로부터 보호하지는 않습니다. 클라이언트에서 이 문제를 처리하지 않으려면 서버에서 기본/파생 할당을 모두 사용하지 않습니다.
형식 DataContractSerializer을 사용할 때
alwaysEmitTypeInformation생성자 매개 변수는 기본값이 "false"인 이전 두 모드 중에서 선택할 수 있게 해줍니다(필요할 때만 형식 힌트를 내보내기).
중복 데이터 멤버 이름
파생 형식 정보는 기본 형식 정보와 함께 동일한 JSON 개체에 있으며 순서에 따라 발생할 수 있습니다. 예를 들어 Shape 다음과 같이 표시될 수 있습니다.
{"__type":"Shape:#MyApp.Shapes","x":50,"y":70}
반면 원이 다음과 같이 표시될 수 있습니다.
{"__type":"Circle:#MyApp.Shapes","x":50, "radius":10,"y":70}
기본 Shape 형식에 "radius"라는 데이터 멤버도 포함된 경우 직렬화(JSON 개체는 반복 키 이름을 가질 수 없기 때문에) 및 역직렬화("radius"가 참조하는지 여부가 불분명하기 때문에)에 충돌이 발생합니다 Shape.radiusCircle.radius. 따라서 "속성 숨기기"(기반 및 파생 클래스에 대해 동일한 이름의 데이터 멤버)의 개념은 일반적으로 데이터 계약 클래스에서 권장되지 않지만 JSON의 경우 실제로 금지됩니다.
다형성 및 IXmlSerializable 형식
IXmlSerializable 일반적인 데이터 계약 규칙에 따라 알려진 형식 요구 사항이 충족되는 한 형식은 일반적으로 서로 다형적으로 할당될 수 있습니다. IXmlSerializable 형식을 Object 형식으로 직렬화하면 결과가 JSON 문자열이 되어 형식 정보가 손실됩니다.
다형성 및 특정 인터페이스 형식
IXmlSerializable을(를) 제외하고 IXmlSerializable이(가) 아닌 비컬렉션 형식이 필요한 경우에 컬렉션 유형이나 Object을(를) 구현하는 유형을 직렬화하는 것은 금지됩니다. 예를 들어, IMyInterface 라는 사용자 지정 인터페이스와 형식 MyType은 IEnumerable<T> 형식 int 및 IMyInterface를 구현합니다. 작업의 반환 형식이 MyType 인 경우 IMyInterface을(를) 반환하는 것이 금지되어 있습니다.
MyType 이는 JSON 배열로 직렬화해야 하고 형식 힌트가 필요하며, 앞에서 설명한 대로 복합 형식만 있는 배열과 함께 형식 힌트를 포함할 수 없기 때문입니다.
알려진 형식 및 구성
모든 알려진 형식 메커니즘은 DataContractSerializer에서 사용하는 것과 동일한 방식으로 DataContractJsonSerializer에서 지원됩니다. 두 직렬 변환기는 system.runtime.serialization<에서> 동일한 구성 요소인 <dataContractSerializer>를 읽고 구성 파일을 통해 추가된 알려진 형식을 검색합니다.
개체에 할당된 컬렉션
Object에 할당된 컬렉션은 복합 형식인 경우 형식 힌트가 있는 각 항목이 있는 JSON 배열을 구현 IEnumerable<T>하는 컬렉션인 것처럼 직렬화됩니다. 예를 들어 형식 List<T>의 Shape가 Object에 할당된 모습은 다음과 같습니다.
[{"__type":"Shape:#MyApp.Shapes","x":50,"y":70},
{"__type":"Shape:#MyApp.Shapes","x":58,"y":73},
{"__type":"Shape:#MyApp.Shapes","x":41,"y":32}]
비직렬화된 경우 Object로:
Shape는 알려진 형식 목록에 있어야 합니다. 알려진 형식에 List<T> 유형이 포함되어 있어도 아무 효과가 없습니다. 이 경우 serialization에서 알려진 형식에 추가할Shape필요가 없습니다. 이 작업은 자동으로 수행됩니다.
기본 컬렉션에 할당된 파생 컬렉션
파생 컬렉션이 기본 컬렉션에 할당되면 컬렉션은 일반적으로 기본 형식의 컬렉션인 것처럼 직렬화됩니다. 그러나 파생 컬렉션의 항목 형식을 기본 컬렉션의 항목 형식에 할당할 수 없는 경우 예외가 throw됩니다.
형식 힌트 및 사전
사전이 Object에 할당되면 사전의 각 키와 값이 Object에 할당된 것처럼 처리되고 타입 힌트를 부여받습니다.
사전 형식을 직렬화할 때 "Key" 및 "Value" 멤버를 포함하는 JSON 개체는 설정의 alwaysEmitTypeInformation 영향을 받지 않으며 이전 컬렉션 규칙에 필요한 경우에만 형식 힌트를 포함합니다.
유효한 JSON 키 이름
serializer XML은 유효한 XML 이름이 아닌 키 이름을 인코딩합니다. 예를 들어 이름이 "123"인 데이터 멤버는 "123"이 잘못된 XML 요소 이름(숫자로 시작)이므로 "_x0031__x0032__x0033_"과 같은 인코딩된 이름을 갖습니다. XML 이름에서 일부 국제 문자 집합이 유효하지 않은 경우 비슷한 상황이 발생할 수 있습니다. JSON 처리에 XML이 미치는 영향에 대한 설명은 JSON과 XML 간의 매핑을 참조하세요.