확장 사전의 속성이 직렬화에 표시되지 않습니다.

콘라드 빌터 스텐

사전 (번역을위한 완벽한 데이터 구조)을 확장하고 어떤 종류의 번역이 수행 될지 알려주는 마커를 추가했습니다.

internal class Translation : Dictionary<string, string>
{
  public string Name { get; set; }
}

그러나 객체를 직렬화하면 출력 문자열에서 키-값 쌍만 가져옵니다. 이름이 표시되지 않습니다. 나는 마이크로 소프트 삼촌의 선물 가방, 즉 System.Text.Json 의 물건을 사용하고 싶었 기 때문에 다음을 수행한다.

string output = JsonSerializer.Serialize(source);

내 의심은 사용자 지정 직렬 변환기를 구현해야한다는 것입니다.하지만이 간단한 경우에는 너무 복잡합니다. 내 경험에 따르면 도구에 번들로 제공되는 깔끔하고 부드러운 접근 방식 (내가 알지 못하는)이 있습니다.

어떻게하나요? 또는 원활하게 가능하지 않은 경우 왜 복잡한 문제입니까 (내가 이해하지 못하는 것 같음)?

아래 양식에 JSON이 필요했습니다.

{
  "name": "donkey",
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
}

물론 name 이고 donkey항목을 사전에 추가하여 해결할 수 있습니다 . 그러나 그 실용적인 해결책은 내 대체물로 저장하는 것을 선호합니다. 지금은 여유 시간이 있고 구조를 가지고 놀아보고 싶습니다. 또한 이름문자열 대신 int되거나 타임 스탬프 등을 설명하는 더 복잡한 구조 가 될 수 있다고 상상할 수 있습니다 . 그것은 사전의 계약을 완전히 깨뜨릴 것입니다 (문자열 대 문자열 매핑).

dbc

이것은 의도 설계 것 같다 - Newtonsoft와 같은를 JavaScriptSerializer하고 DataContractJsonSerializer, 사전 키와 값은 일반 속성,하지 직렬화된다.

확장의 대안으로 Dictionary<TKey, TValue>컨테이너 클래스에서 사전을 캡슐화하고 사전을 다음으로 표시하여 원하는 JSON을 얻을 수 있습니다 JsonExtensionDataAttribute.

internal class Translation
{
    public string Name { get; set; }

    [JsonExtensionData]
    public Dictionary<string, object> Data { get; set; } = new Dictionary<string, object>();
}

그리고 다음과 같이 직렬화합니다.

var translation = new Translation
{
    Name = "donkey",
    Data = 
    {
        {"key1", "value1"},
        {"key2", "value2"},
        {"key3", "value3"},
    },
};

var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    // Other options as required
    WriteIndented = true,
};

var json = JsonSerializer.Serialize(translation, options);

문서 에서이 제한 사항을 확인하십시오.

사전의 TKey 값은 String 이고 TValue는 JsonElement 또는 Object 여야합니다 .

(제쳐두고, 유사한 접근 방식이 자체 .NET JsonExtensionDataAttribute라이브러리 가있는 Newtonsoft에서 작동 합니다. 두 라이브러리를 모두 사용하는 경우 속성을 혼동하지 않도록하십시오.)

데모 바이올린 # 1 여기 .

데이터 모델에 대한 이러한 수정이 편리하지 않은 JsonConverter<Translation>경우 위의 모델과 같이 DTO를 (비) 직렬화 한 다음 최종 모델에서 DTO를 매핑 하는 사용자 지정 도입 할 수 있습니다 .

internal class Translation : Dictionary<string, string>
{
    public string Name { get; set; }
}

internal class TranslationConverter : JsonConverter<Translation>
{
    internal class TranslationDTO
    {
        public string Name { get; set; }

        [JsonExtensionData]
        public Dictionary<string, object> Data { get; set; }
    }

    public override Translation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var dto = JsonSerializer.Deserialize<TranslationDTO>(ref reader, options);
        if (dto == null)
            return null;
        var translation = new Translation { Name = dto.Name };
        foreach (var p in dto.Data)
            translation.Add(p.Key, p.Value?.ToString());
        return translation;
    }

    public override void Write(Utf8JsonWriter writer, Translation value, JsonSerializerOptions options)
    {
        var dto = new TranslationDTO { Name = value.Name, Data = value.ToDictionary(p => p.Key, p => (object)p.Value) };
        JsonSerializer.Serialize(writer, dto, options);
    }
}

그리고 다음과 같이 직렬화합니다.

var translation = new Translation
{
    Name = "donkey",
    ["key1"] = "value2",
    ["key2"] = "value2",
    ["key3"] = "value3",
};

var options = new JsonSerializerOptions
{
    Converters = { new TranslationConverter() },
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    // Other options as required
    WriteIndented = true,
};

var json = JsonSerializer.Serialize(translation, options);

내가 직접 일하는 DTO 오히려보다 (드) 직렬화가 간단하게 찾을 수 Utf8JsonReaderUtf8JsonWriter에지의 경우와 같은 및 명명 정책을 자동으로 처리하세요. 성능이 중요한 경우에만 독자 및 작가와 직접 협력합니다.

두 방법 모두 JSON 에서 모델에 JsonNamingPolicy.CamelCase바인딩 "name"하는 데 필요합니다 Name.

데모 바이올린 # 2 여기 .

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

iOS 7 앱의 확장 버전에서 상태 표시 줄이 사라지지 않습니다.

분류에서Dev

내 Visual Studio 코드 확장이 사이드 바에 표시되지 않습니다.

분류에서Dev

Devise 등록 확인에 메일이 전송되었다고 표시되지만 사용자에게 이러한 메시지가 표시되지 않습니다.

분류에서Dev

FOSUserBundle의 BaseUser에서 확장하는 동안 속성이 정의되지 않았습니다.

분류에서Dev

UIA 확인에 버튼의 이름 속성이 표시되지 않음

분류에서Dev

총 가격이 PHP의 장바구니에 표시되지 않았습니다.

분류에서Dev

속성이 직렬화 배열 목록에 기록되지 않습니다.

분류에서Dev

Opera mini에서 자리 표시 자 속성이 감지되었지만 사용되지 않았습니다.

분류에서Dev

Typo3 : 확장 모듈에 확장 가져 오기 옵션이 표시되지 않습니다.

분류에서Dev

양식 제출에 내 사용자 정의 확인란이 다음과 같이 표시되지 않습니다.

분류에서Dev

mapView의 사용자 위치가 여러 시뮬레이터 장치 (MapKit)에 표시되지 않습니다.

분류에서Dev

속성이 XML 속성으로 직렬화되지 않습니다.

분류에서Dev

이름에 쉼표를 사용하여 JSON 속성 이름을 직렬화 하시겠습니까?

분류에서Dev

AMP 유효성 검사 오류 : 'cite'속성이 'q'태그에 표시되지 않을 수 있습니다.

분류에서Dev

확장 속성의 Odata 필터링이 작동하지 않습니다.

분류에서Dev

Android googlemap이 실제 장치에 표시되지 않습니다.

분류에서Dev

Breeze js 엔티티의 속성을 확장하면 변경 사항이 추적되지 않습니다.

분류에서Dev

Apollo 서버는 하위 개체에서 Mongoose의 가상 속성을 직렬화하지 않습니다.

분류에서Dev

다운로드 한 첨부 파일에 올바른 확장자 이름이 표시되지 않습니다.

분류에서Dev

다운로드 한 첨부 파일에 올바른 확장자 이름이 표시되지 않습니다.

분류에서Dev

Symfony-양식에 나뭇 가지 확장을 사용하면 오류가 표시되지 않습니다.

분류에서Dev

WordPress의 CKeditor에 이미지가 표시되지 않습니다.

분류에서Dev

할당 전에 물결표 접두사가 확장되지만 중괄호는 확장되지 않는 이유

분류에서Dev

승인 및 게시 된 Google OAuth 동의 화면에 여전히 '이 앱은 확인되지 않았습니다.'오류가 표시됨

분류에서Dev

ADT에서 Drawerlayout을 사용할 때 옵션 목록에 layout_width 속성이 표시되지 않습니다.

분류에서Dev

Visual Studio IntelliSense for UIAutomation의 AutomationElement 클래스에 모든 속성이 표시되지는 않습니다.

분류에서Dev

수정 필요 ... 'width'속성이 AMP HTML의 'col'태그에 표시되지 않을 수 있습니다.

분류에서Dev

iOS 8 Beta Today 확장 위젯이 Swift 앱에 표시되지 않습니까?

분류에서Dev

디자이너는 UserControl의 DataGridView 속성의 열을 직렬화하지 않습니다.

Related 관련 기사

  1. 1

    iOS 7 앱의 확장 버전에서 상태 표시 줄이 사라지지 않습니다.

  2. 2

    내 Visual Studio 코드 확장이 사이드 바에 표시되지 않습니다.

  3. 3

    Devise 등록 확인에 메일이 전송되었다고 표시되지만 사용자에게 이러한 메시지가 표시되지 않습니다.

  4. 4

    FOSUserBundle의 BaseUser에서 확장하는 동안 속성이 정의되지 않았습니다.

  5. 5

    UIA 확인에 버튼의 이름 속성이 표시되지 않음

  6. 6

    총 가격이 PHP의 장바구니에 표시되지 않았습니다.

  7. 7

    속성이 직렬화 배열 목록에 기록되지 않습니다.

  8. 8

    Opera mini에서 자리 표시 자 속성이 감지되었지만 사용되지 않았습니다.

  9. 9

    Typo3 : 확장 모듈에 확장 가져 오기 옵션이 표시되지 않습니다.

  10. 10

    양식 제출에 내 사용자 정의 확인란이 다음과 같이 표시되지 않습니다.

  11. 11

    mapView의 사용자 위치가 여러 시뮬레이터 장치 (MapKit)에 표시되지 않습니다.

  12. 12

    속성이 XML 속성으로 직렬화되지 않습니다.

  13. 13

    이름에 쉼표를 사용하여 JSON 속성 이름을 직렬화 하시겠습니까?

  14. 14

    AMP 유효성 검사 오류 : 'cite'속성이 'q'태그에 표시되지 않을 수 있습니다.

  15. 15

    확장 속성의 Odata 필터링이 작동하지 않습니다.

  16. 16

    Android googlemap이 실제 장치에 표시되지 않습니다.

  17. 17

    Breeze js 엔티티의 속성을 확장하면 변경 사항이 추적되지 않습니다.

  18. 18

    Apollo 서버는 하위 개체에서 Mongoose의 가상 속성을 직렬화하지 않습니다.

  19. 19

    다운로드 한 첨부 파일에 올바른 확장자 이름이 표시되지 않습니다.

  20. 20

    다운로드 한 첨부 파일에 올바른 확장자 이름이 표시되지 않습니다.

  21. 21

    Symfony-양식에 나뭇 가지 확장을 사용하면 오류가 표시되지 않습니다.

  22. 22

    WordPress의 CKeditor에 이미지가 표시되지 않습니다.

  23. 23

    할당 전에 물결표 접두사가 확장되지만 중괄호는 확장되지 않는 이유

  24. 24

    승인 및 게시 된 Google OAuth 동의 화면에 여전히 '이 앱은 확인되지 않았습니다.'오류가 표시됨

  25. 25

    ADT에서 Drawerlayout을 사용할 때 옵션 목록에 layout_width 속성이 표시되지 않습니다.

  26. 26

    Visual Studio IntelliSense for UIAutomation의 AutomationElement 클래스에 모든 속성이 표시되지는 않습니다.

  27. 27

    수정 필요 ... 'width'속성이 AMP HTML의 'col'태그에 표시되지 않을 수 있습니다.

  28. 28

    iOS 8 Beta Today 확장 위젯이 Swift 앱에 표시되지 않습니까?

  29. 29

    디자이너는 UserControl의 DataGridView 속성의 열을 직렬화하지 않습니다.

뜨겁다태그

보관