your programing

Json.Net의 개인 세터

lovepro 2020. 10. 9. 11:34
반응형

Json.Net의 개인 세터


개인 setter를 처리하는 속성이 있다는 것을 알고 있지만이 동작을 기본값으로 원합니다.이를 수행하는 방법이 있습니까? 소스 조정을 제외하고. 이것에 대한 설정이 있다면 좋을 것입니다.


역 직렬화 할 때 Json.NET이 읽기 전용 속성을 채우도록 만드는 실제 속성을 찾고 있습니다 [JsonProperty]. 예를 들면 다음과 같습니다.

[JsonProperty]
public Guid? ClientId { get; private set; }

대체 솔루션

속성과 일치하는 매개 변수가있는 생성자를 제공하기 만하면됩니다.

public class Foo
{
    public string Bar { get; }

    public Foo(string bar)
    {
        Bar = bar;
    }
}

이제 작동합니다.

string json = "{ \"bar\": \"Stack Overflow\" }";

var deserialized = JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine(deserialized.Bar); // Stack Overflow

가능한 경우이 접근 방식을 선호합니다.

  • 속성으로 속성을 장식 할 필요가 없습니다.
  • 그것은 모두 { get; private set; }및 단지 { get; }.

업데이트 된 새로운 답변

두 개의 사용자 지정 계약 해결 프로그램이있는 단일 파일을 설치하는 소스 배포 NuGet을 작성했습니다.

  • PrivateSetterContractResolver
  • PrivateSetterCamelCasePropertyNamesContractResolver

NuGet을 설치합니다.

Install-Package JsonNet.PrivateSettersContractResolvers.Source

그런 다음 리졸버 중 하나를 사용하십시오.

var settings = new JsonSerializerSettings
{
    ContractResolver = new PrivateSetterContractResolver()
};

var model = JsonConvert.DeserializeObject<Model>(json, settings);

여기에서 읽을 수 있습니다 : http://danielwertheim.se/json-net-private-setters-nuget/

GitHub repo : https://github.com/danielwertheim/jsonnet-privatesetterscontractresolvers

이전 답변 (아직 유효 함)

문제를 해결할 수있는 두 가지 대안이 있습니다.

Alt 1 : 역 직렬화 기에서

ContractResolver.DefaultMembersSearchFlags =
                             DefaultMembersSearchFlags | BindingFlags.NonPublic;

기본 직렬화 옵션은 모든 유형의 클래스 멤버를 지원합니다. 따라서이 솔루션은 필드를 포함한 모든 개인 멤버 유형을 반환합니다. 나는 또한 개인 세터를 지원하는 데 관심이 있습니다.

Alt2 : 사용자 정의 ContractResolver 생성 :

따라서 속성 만 확인하기 때문에 이것이 더 나은 옵션입니다.

public class SisoJsonDefaultContractResolver : DefaultContractResolver 
{
    protected override JsonProperty CreateProperty(
        MemberInfo member,
        MemberSerialization memberSerialization)
    {
        //TODO: Maybe cache
        var prop = base.CreateProperty(member, memberSerialization);

        if (!prop.Writable)
        {
            var property = member as PropertyInfo;
            if (property != null)
            {
                var hasPrivateSetter = property.GetSetMethod(true) != null;
                prop.Writable = hasPrivateSetter;
            }
        }

        return prop;
    }
}

자세한 내용은 내 게시물을 읽으십시오. http://danielwertheim.se/json-net-private-setters/


@Daniel's answer (Alt2) is spot on, but I needed this to work for both private setters and getters (I'm working with an API that actually has a few write-only things, like user.password.) Here's what I ended up with:

public class NonPublicPropertiesResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
        var prop = base.CreateProperty(member, memberSerialization);
        if (member is PropertyInfo pi) {
            prop.Readable = (pi.GetMethod != null);
            prop.Writable = (pi.SetMethod != null);
        }
        return prop;
    }
}

Registered thusly:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
    ContractResolver = new NonPublicPropertiesResolver()
};

참고URL : https://stackoverflow.com/questions/4066947/private-setters-in-json-net

반응형