NET 使用根名称序列化对象

在我的网络应用程序中,我使用的是 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;}
}

我想用根名称(类名称)序列化它们

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

我知道我可以用匿名对象做到这一点,但在 Newtonsoft 任何财产或其他方式。杰森图书馆?

142514 次浏览

使用匿名类

使用匿名类按照您希望的方式塑造模型:

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


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

对于根元素,请使用 GlobalConfiguration。

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

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

我找到了一个简单的方法来呈现它... ... 只需声明一个动态对象,并将动态对象中的第一个项分配给您的集合类... ... 这个例子假设您正在使用 Newtonsoft。杰森

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

你最终应该得到的是这样的东西:

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

那么,您至少可以告诉 Json.NET 包含类型名称: http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_TypeNameHandling.htm。< 代码 > Newtonsoft。杰森。JsonSerializer jser = new Newtonsoft.杰森。JsonSerializer () ; 类型名称处理 = 类型名称处理对象;

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

这并不完全是你想要的,但是当我遇到类似的问题时,这对我来说已经足够好了。

希望这个能帮上忙。

//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="john@domain.com"
};
var serializedObject = customer.JsonSerialize();
[Newtonsoft.Json.JsonObject(Title = "root")]
public class TestMain

这是唯一需要添加以使代码工作的属性。

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

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

当你要进行序列化的时候:

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

最后,你会看到你所期望的结果如下:

{
"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"
}
]
}

希望这个能帮上忙!

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

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

此代码生成以下 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
]
]
}
}

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

一种可能的实施办法是:

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