使用自定义结构将C#类转换为Json

时间:2018-12-12 05:05:12

标签: c# json serialization json.net deserialization

我们的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 用于。对于某些选定的属性,我们需要像这样序列化。另外,我们需要从JSON读取并反序列化到类中。我们可以通过装饰元素来遵循通用最佳方法吗?

4 个答案:

答案 0 :(得分:2)

当您用标记问题时,可以通过对在序列化时应嵌套在{"value" : ... }对象中的“选定属性”应用custom 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);

注意:

提琴here

答案 1 :(得分:1)

此处前缀标题也是类而不是字符串。 在这里,您的班级要看起来像这样。

#include <iostream>
using namespace std;

int main()
{
    int a;
    int ex;
    for (a = 1; a <= 5; a++)
    {
        for(int i = 0; i < a; ++i)
        {
            cout<<"*";
        }
        for(ex =1; ex<= 2*a; ex++)
        {
            cout<<"!";
        }
        cout<<endl;
    }
    return 0;
}

将Newtonsoft.json libraby文件安装到您的项目中:-> 在Tools NuGet Package中打开Package Manager控制台并将其粘贴,然后按Enter

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;}
}

将课程转换为Json:

Install-Package Newtonsoft.Json -Version 12.0.1

将Json转换为对象:

这里的对象表示一个类

string output = JsonConvert.SerializeObject(classname);

在这里您可以找到可直接在项目中使用的优化代码:

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;
}

仅此而已。.

我希望这可以为您提供帮助。

答案 2 :(得分:0)

您可以通过更改模型来实现此目的,例如:

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>();

答案 3 :(得分:0)

您需要为您的对象编写自定义序列化程序。这是一个示例,展示了如何通过扩展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"
    }
}