簡體   English   中英

使用自定義結構將C#類轉換為Json

[英]Convert C# class to Json with customized structure

我們有如下的C#類

public class PrimaryContact
{
   public string PrefixTitle { get; set; }

   public string SurName { get; set; }

   public string GivenName { get; set; }
}

我們需要序列化為json對象為

"primaryContact": {
      "prefixTitle": {
        "value": "mrs"
      },
      "surName": "abcd",
      "givenName": "abcd"      
    }

請注意prefixTitle是與value一起使用的 對於某些選定的屬性,我們需要像這樣序列化。 另外,我們需要從JSON讀取並反序列化到類中。 我們是否可以通過裝飾元素來遵循通用的最佳方法,以便獲得此結果?

當您用標記問題時,可以通過對序列化時應嵌套在{"value" : ... }對象內的“ selected JsonConverter ”應用自定義JsonConverter來實現。

首先,定義以下轉換器:

public class NestedValueConverter<T> : JsonConverter
{
    class Value
    {
        public T value { get; set; }
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        switch (reader.MoveToContent().TokenType)
        {
            case JsonToken.Null:
                return null;

            default:
                return serializer.Deserialize<Value>(reader).value;
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, new Value { value = (T)value });
    }
}

public static partial class JsonExtensions
{
    public static JsonReader MoveToContent(this JsonReader reader)
    {
        if (reader.TokenType == JsonToken.None)
            reader.Read();
        while (reader.TokenType == JsonToken.Comment && reader.Read())
            ;
        return reader;
    }
}

現在,將其應用於PrimaryContact的“選定屬性”,如下所示:

public class PrimaryContact
{
    [JsonConverter(typeof(NestedValueConverter<string>))]
    public string PrefixTitle { get; set; }

    public string SurName { get; set; }

    public string GivenName { get; set; }
}

然后,您將可以反序列化和序列化,如下所示:

var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
};
var root = JsonConvert.DeserializeObject<RootObject>(jsonString, settings);

var json2 = JsonConvert.SerializeObject(root, Formatting.Indented, settings);

筆記:

樣品在這里擺弄。

這里的前綴標題也是一個類而不是字符串。 在這里,您的班級要看起來像這樣。

public class PrimaryContact
{
   public PrefixTitle prefixTitle{ get; set; }

   public string surName{ get; set; }

   public string givenName{ get; set; }
}

public class PrefixTitle {
   public string value {get; set;}
}

將Newtonsoft.json libraby文件安裝到您的項目:-> 在Tools NuGet Package中打開Package Manager控制台並將其粘貼,然后按Enter

Install-Package Newtonsoft.Json -Version 12.0.1

將類轉換為Json:

string output = JsonConvert.SerializeObject(classname);

將Json轉換為Object:

這里的object表示一個Class

Object output = JsonConvert.DeSerializeObject<object>(jsonString);

在這里,您可以找到可直接在項目中使用的優化代碼:

public static string getJsonFromClass(object objectName){
    return JsonConvert.SerializeObject(object);
}

public static T getObjectFromJson<T>(string jsonString){
    T t = default(T);
    try{
       t = JsonConvert.DeSerializeObject<T>(classname);
    }catch(Exception e){
       Debug.WriteLine(e.Message);
    }
    return t;
}

您可以通過以下方法使用此方法來實現輸出:

string jsonData = getJsonFromClass(Prefix);

string JsonString = "<here your json string>";

Prefix getObjectFromJson = getObjectFromJson<Prefix>(JsonString);

就這樣 ..

希望對您有幫助。

您可以通過更改模型來實現此目的,例如:

public class PrimaryContact
{
   public Prefix PrefixTitle  { get; set; }

   public string SurName { get; set; }

   public string GivenName { get; set; }
}

public class Prefix
{
   public string Value  { get; set; }
}

然后

Newton.Json.JsonConvert.DeserializeObject<PrimaryContact>();

您需要為您的對象編寫自定義序列化程序。 這是一個示例,展示了如何通過擴展JsonConverter並使用一些自定義屬性來確定是否應該包裝您的對象/屬性來執行此操作:

[WrapperAttribute(Key = "primaryContact")]
public class PrimaryContact
{
    [WrapperAttribute(Key= "prefixTitle")]
    public string PrefixTitle { get; set; }

    public string SurName { get; set; }

    public string GivenName { get; set; }
}

public class WrapperAttribute : Attribute
{
    public string Key { get; set; }
}


public class WrapperSerializer : JsonConverter<PrimaryContact>
{
    public override void WriteJson(JsonWriter writer, PrimaryContact value, JsonSerializer serializer)
    {
        Type type = value.GetType();

        JObject root = new JObject();

        foreach (var property in type.GetAllProperties())
        {
            if (property.HasAttribute<WrapperAttribute>())
            {
                JProperty wrappedProperty = new JProperty(property.GetAttribute<WrapperAttribute>().Key);
                JObject wrappedChild = new JObject();
                wrappedProperty.Value = wrappedChild;

                JProperty wrappedChildProperty = new JProperty("value");
                wrappedChildProperty.Value = JToken.FromObject(property.GetValue(value));

                wrappedChild.Add(wrappedChildProperty);

                root.Add(wrappedProperty);
            }
            else
            {
                var childProperty = new JProperty(property.Name);

                childProperty.Value = JToken.FromObject(property.GetValue(value));
                root.Add(childProperty);
            }

        }

        if (type.HasAttribute<WrapperAttribute>())
        {
            JObject wrappedRoot = new JObject();
            var wrappedProperty = new JProperty(type.GetAttribute<WrapperAttribute>().Key);
            wrappedProperty.Value = root;
            wrappedRoot.Add(wrappedProperty);
            wrappedRoot.WriteTo(writer);
        }
        else
        {
            root.WriteTo(writer);
        }

    }

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

在主要方面:

PrimaryContact contact = new PrimaryContact();
contact.GivenName = "test name";
contact.PrefixTitle = "test title";
contact.SurName = "test surname";

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new WrapperSerializer());

var serialized = JsonConvert.SerializeObject(contact, settings);

輸出:

{
    "primaryContact": {
        "prefixTitle": {
            "value": "test title"
        },
        "SurName": "test surname",
        "GivenName": "test name"
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM