C# Json.NET 使用根名称序列化对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16294963/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:40:32  来源:igfitidea点击:

Json.NET serialize object with root name

c#asp.net.netjsonjson.net

提问by user2034092

In my web app I'm using Newtonsoft.Json and I have following object

在我的网络应用程序中,我使用的是 Newtonsoft.Json 并且我有以下对象

[Newtonsoft.Json.JsonObject(Title = "MyCar")]
public class Car
{
    [Newtonsoft.Json.JsonProperty(PropertyName = "name")]
    public string Name{get;set;}

    [Newtonsoft.Json.JsonProperty(PropertyName = "owner")]
    public string Owner{get;set;}
}

and I want serialize them with root name (class name). This is desired format using

我想用根名称(类名)序列化它们。这是使用所需的格式

{'MyCar':
 {
   'name': 'Ford',
   'owner': 'John Smith'
 }
}

I know that I can do that with anonymous object, but is any property or another way in Newtonsoft.Json library?

我知道我可以用匿名对象做到这一点,但是 Newtonsoft.Json 库中有任何属性或其他方式吗?

回答by Andrei

Use anonymous class

使用匿名类

Shape your model the way you want using anonymous classes:

使用匿名类以您想要的方式塑造您的模型:

var root = new 
{ 
    car = new 
    { 
        name = "Ford", 
        owner = "Henry"
    }
};

string json = JsonConvert.SerializeObject(root);

回答by Newton Sheikh

string Json = JsonConvert.SerializeObject(new Car { Name = "Ford", Owner = "John Smith" }, Formatting.None);

for the root element use GlobalConfiguration.

对于根元素使用 GlobalConfiguration。

回答by I4V

You can easily create your own serializer

您可以轻松创建自己的序列化程序

var car = new Car() { Name = "Ford", Owner = "John Smith" };
string json = Serialize(car);


string Serialize<T>(T o)
{
    var attr = o.GetType().GetCustomAttribute(typeof(JsonObjectAttribute)) as JsonObjectAttribute;

    var jv = JValue.FromObject(o);

    return new JObject(new JProperty(attr.Title, jv)).ToString();
}

回答by Matthew Merryfull

I found an easy way to render this out... simply declare a dynamic object and assign the first item within the dynamic object to be your collection class...This example assumes you're using Newtonsoft.Json

我找到了一种简单的方法来渲染它...只需声明一个动态对象并将动态对象中的第一项分配为您的集合类...此示例假设您使用的是 Newtonsoft.Json

private class YourModelClass
{
    public string firstName { get; set; }
    public string lastName { get; set; }
}

var collection = new List<YourModelClass>();

var collectionWrapper = new {

    myRoot = collection

};

var output = JsonConvert.SerializeObject(collectionWrapper);

What you should end up with is something like this:

你最终应该是这样的:

{"myRoot":[{"firstName":"John", "lastName": "Citizen"}, {...}]}

回答by Radovan Jankovic

Well, you can at least tell Json.NET to include the type name: http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm. Newtonsoft.Json.JsonSerializer jser = new Newtonsoft.Json.JsonSerializer(); jser.TypeNameHandling = TypeNameHandling.Objects;

好吧,您至少可以告诉 Json.NET 包含类型名称:http: //www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htmNewtonsoft.Json.JsonSerializer jser = new Newtonsoft.Json.JsonSerializer(); jser.TypeNameHandling = TypeNameHandling.Objects;

The type will be included at the beginning in the "$type" property of the object.

该类型将包含在对象的“$type”属性的开头。

This is not exactly what you are looking for, but it was good enough for me when facing a similiar problem.

这不完全是您要找的东西,但是当我遇到类似的问题时,这对我来说已经足够了。

回答by Monkey Programmer

I hope this help.

我希望这会有所帮助。

//Sample of Data Contract:

[DataContract(Name="customer")]
internal class Customer {
  [DataMember(Name="email")] internal string Email { get; set; }
  [DataMember(Name="name")] internal string Name { get; set; }
}

//This is an extension method useful for your case:

public static string JsonSerialize<T>(this T o)
{
  MemoryStream jsonStream = new MemoryStream();
  var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
  serializer.WriteObject(jsonStream, o);

  var jsonString = System.Text.Encoding.ASCII.GetString(jsonStream.ToArray());

  var props = o.GetType().GetCustomAttributes(false);
  var rootName = string.Empty;
  foreach (var prop in props)
  {
    if (!(prop is DataContractAttribute)) continue;
    rootName = ((DataContractAttribute)prop).Name;
    break;
  }
  jsonStream.Close();
  jsonStream.Dispose();

  if (!string.IsNullOrEmpty(rootName)) jsonString = string.Format("{{ \"{0}\": {1} }}", rootName, jsonString);
  return jsonString;
}

//Sample of usage

var customer = new customer { 
Name="John",
Email="[email protected]"
};
var serializedObject = customer.JsonSerialize();

回答by gmuonio

[Newtonsoft.Json.JsonObject(Title = "root")]
public class TestMain

this is the only attrib you need to add to get your code working.

这是您需要添加才能使代码正常工作的唯一属性。

回答by jet_choong

A very simple approach for me is just to create 2 classes.

对我来说一个非常简单的方法就是创建 2 个类。

public class ClassB
{
    public string id{ get; set; }
    public string name{ get; set; }
    public int status { get; set; }
    public DateTime? updated_at { get; set; }
}

public class ClassAList
{
    public IList<ClassB> root_name{ get; set; } 
}

And when you going to do serialization:

当您要进行序列化时:

var classAList = new ClassAList();
//...
//assign some value
//...
var jsonString = JsonConvert.SerializeObject(classAList)

Lastly, you will see your desired result as the following:

最后,您将看到您想要的结果如下:

{
  "root_name": [
    {
      "id": "1001",
      "name": "1000001",
      "status": 1010,
      "updated_at": "2016-09-28 16:10:48"
    },
    {
      "id": "1002",
      "name": "1000002",
      "status": 1050,
      "updated_at": "2016-09-28 16:55:55"
    }
  ]
}

Hope this helps!

希望这可以帮助!

回答by user2440841

Sorry, my english is not that good. But i like to improve the upvoted answers. I think that using Dictionary is more simple and clean.

对不起,我的英语不是很好。但我喜欢改进赞成的答案。我认为使用 Dictionary 更简单和干净。

class Program
    {
        static void Main(string[] args)
        {
            agencia ag1 = new agencia()
            {
                name = "Iquique",
                data = new object[] { new object[] {"Lucas", 20 }, new object[] {"Fernando", 15 } }
            };
            agencia ag2 = new agencia()
            {
                name = "Valparaiso",
                data = new object[] { new object[] { "Rems", 20 }, new object[] { "Perex", 15 } }
            };
            agencia agn = new agencia()
            {
                name = "Santiago",
                data = new object[] { new object[] { "Jhon", 20 }, new object[] { "Karma", 15 } }
            };


            Dictionary<string, agencia> dic = new Dictionary<string, agencia>
            {
                { "Iquique", ag1 },
                { "Valparaiso", ag2 },
                { "Santiago", agn }
            };

            string da = Newtonsoft.Json.JsonConvert.SerializeObject(dic);

            Console.WriteLine(da);
            Console.ReadLine();
        }


    }

    public class agencia
    {
        public string name { get; set; }
        public object[] data { get; set; }
    }

This code generate the following json (This is desired format)

此代码生成以下 json(这是所需的格式)

{  
   "Iquique":{  
      "name":"Iquique",
      "data":[  
         [  
            "Lucas",
            20
         ],
         [  
            "Fernando",
            15
         ]
      ]
   },
   "Valparaiso":{  
      "name":"Valparaiso",
      "data":[  
         [  
            "Rems",
            20
         ],
         [  
            "Perex",
            15
         ]
      ]
   },
   "Santiago":{  
      "name":"Santiago",
      "data":[  
         [  
            "Jhon",
            20
         ],
         [  
            "Karma",
            15
         ]
      ]
   }
}

回答by prusswan

Writing a custom JsonConverteris another approach mentioned in similar questions. However, due to nature of how JsonConverteris designed, using that approach for this question is tricky, as you need to be careful with the WriteJsonimplementation to avoid getting into infinite recursion: JSON.Net throws StackOverflowException when using [JsonConvert()].

编写自定义JsonConverter是类似问题中提到的另一种方法。但是,由于JsonConverter设计方式的性质,对这个问题使用这种方法很棘手,因为您需要小心WriteJson实现以避免陷入无限递归:JSON.Net 在使用 [JsonConvert()] 时抛出 StackOverflowException

One possible implementation:

一种可能的实现:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    //JToken t = JToken.FromObject(value); // do not use this! leads to stack overflow
    JsonObjectContract contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(value.GetType());

    writer.WriteStartObject();
    writer.WritePropertyName(value.GetType().Name);
    writer.WriteStartObject();
    foreach (var property in contract.Properties)
    {
        // this removes any property with null value
        var propertyValue = property.ValueProvider.GetValue(value);
        if (propertyValue == null) continue;

        writer.WritePropertyName(property.PropertyName);
        serializer.Serialize(writer, propertyValue);
        //writer.WriteValue(JsonConvert.SerializeObject(property.ValueProvider.GetValue(value))); // this adds escaped quotes
    }
    writer.WriteEndObject();
    writer.WriteEndObject();
}