programing

JSON 만드는 법특정 유형을 시리얼화할 때 ToString()을 호출하는 Net serializer?

abcjava 2023. 3. 17. 19:29
반응형

JSON 만드는 법특정 유형을 시리얼화할 때 ToString()을 호출하는 Net serializer?

저는 뉴턴소프트를 사용하고 있습니다.C# 클래스를 JSON으로 변환하는 Json 시리얼라이저.클래스에 따라서는 개별 속성에 대한 인스턴스로의 시리얼라이저가 필요 없고 오브젝트 상에서 ToString을 호출하기만 하면 됩니다.

public class Person
{
   public string FirstName { get; set; }
   public string LastName { get; set; }

   public override string ToString() { return string.Format("{0} {1}", FirstName, LastName ); }
}

ToString() 메서드의 결과로 Person 객체를 시리얼화하려면 어떻게 해야 합니까?이런 클래스가 많을 수 있기 때문에 Person 클래스에 특화된 시리얼라이저를 사용하고 싶지 않습니다.어느 classe에도 적용할 수 있는 클래스(속성)를 사용하고 싶습니다.

커스텀을 사용하면 간단하게 할 수 있습니다.

public class ToStringJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(value.ToString());
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

변환기를 사용하려면 문자열로 일련화할 필요가 있는 클래스를 모두 다음 명령어로 장식합니다.[JsonConverter]다음과 같은 속성:

[JsonConverter(typeof(ToStringJsonConverter))]
public class Person
{
    ...
}

다음은 컨버터의 동작을 보여주는 데모입니다.

class Program
{
    static void Main(string[] args)
    {
        Company company = new Company
        {
            CompanyName = "Initrode",
            Boss = new Person { FirstName = "Head", LastName = "Honcho" },
            Employees = new List<Person>
            {
                new Person { FirstName = "Joe", LastName = "Schmoe" },
                new Person { FirstName = "John", LastName = "Doe" }
            }
        };

        string json = JsonConvert.SerializeObject(company, Formatting.Indented);
        Console.WriteLine(json);
    }
}

public class Company
{
    public string CompanyName { get; set; }
    public Person Boss { get; set; }
    public List<Person> Employees { get; set; }
}

[JsonConverter(typeof(ToStringJsonConverter))]
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public override string ToString() 
    { 
        return string.Format("{0} {1}", FirstName, LastName); 
    }
}

출력:

{
  "CompanyName": "Initrode",
  "Boss": "Head Honcho",
  "Employees": [
    "Joe Schmoe",
    "John Doe"
  ]
}

스트링에서 오브젝트로 변환할 수도 있는 경우ReadJson컨버터상의 메서드를 검색한다.public static Parse(string)메서드를 호출합니다.주의: 반드시 컨버터의CanRead반환 방법true(또는 삭제만 하면 됩니다).CanRead완전히 과부하)하지 않으면ReadJson절대 불리지 않을 거야

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    MethodInfo parse = objectType.GetMethod("Parse", new Type[] { typeof(string) });
    if (parse != null && parse.IsStatic && parse.ReturnType == objectType)
    {
        return parse.Invoke(null, new object[] { (string)reader.Value });
    }

    throw new JsonException(string.Format(
        "The {0} type does not have a public static Parse(string) method that returns a {0}.", 
        objectType.Name));
}

물론 위의 작업을 수행하려면 적절한 기능을 구현해야 합니다.Parse메서드가 아직 존재하지 않는 경우 변환하는 각 클래스의 메서드를 지정합니다.이 예에서는Person위의 클래스는 다음과 같습니다.

public static Person Parse(string s)
{
    if (string.IsNullOrWhiteSpace(s))
        throw new ArgumentException("s cannot be null or empty", "s");

    string[] parts = s.Split(new char[] { ' ' }, 2);
    Person p = new Person { FirstName = parts[0] };
    if (parts.Length > 1)
        p.LastName = parts[1];

    return p;
}

왕복 데모 : https://dotnetfiddle.net/fd4EG4

대규모 사용을 의도하지 않은 경우에는 RecordType 속성에서 이 작업을 수행하는 것이 더 빠릅니다.

[JsonIgnore]
public RecordType RecType { get; set; }

[JsonProperty(PropertyName = "RecordType")]
private string RecordTypeString => RecType.ToString();

이러한 코드를 사용하여 Newtonsoft의 JSON Builder 라이브러리와 Person 유형의 개체를 Serilaize할 수 있습니다.

Dictionary<string, object> collection = new Dictionary<string, object>()
    {
      {"First", new Person(<add FirstName as constructor>)},
      {"Second", new Person(<add LastName as constructor>)},

    };
string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
  {
    TypeNameHandling = TypeNameHandling.All,
    TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
  });

솔루션을 테스트할 시간은 없지만, 잘 될 것입니다.사용하고 있는 모든 클래스가 자신의 클래스라고 가정하면, 모든 클래스와 Newtonsoft를 사용해야 하는 클래스에서 ToString을 덮어쓰면 어떨까요?Json serializer는 ToString 메서드 내에서만 직렬화되어 반환될 수 있습니다.이렇게 하면 오브젝트의 시리얼화 문자열을 취득할 때 언제든지 ToString을 호출할 수 있습니다.

언급URL : https://stackoverflow.com/questions/22354867/how-to-make-json-net-serializer-to-call-tostring-when-serializing-a-particular

반응형