[英]Serialize object to JSON that already contains one JSON property
In order to increase performance, I have cached the result of a larger operation as JSON in a table - together with a key column to determine which row(s) to return.为了提高性能,我将更大操作的结果作为 JSON 缓存在一个表中 - 连同一个键列来确定要返回的行。 So the data looks some like this:
所以数据看起来像这样:
Id Json
---- ---------
1 {"property": "data", "...": "..."}
2 {"property": "data", "...": "..."}
Hence, my retrieved object has the properties int .Id
and string .Json
.因此,我检索到的对象具有属性 int
.Id
和 string .Json
。 When returning such an object with the Id, I first need to deserialize the JSON - so that it gets properly re-serialized.当使用 Id 返回这样的对象时,我首先需要反序列化 JSON - 以便正确地重新序列化。 If I don't deserialize it first, I end up with a quoted string, ie my return object would look like this
如果我不先反序列化它,我最终会得到一个带引号的字符串,即我的返回对象看起来像这样
{
"id": 1,
"json": "{\"property\": \"data\", ...
}
Instead, I need:相反,我需要:
{
"id": 1,
"json": {
"property": "data",
...
}
}
Is there a way to "tell" the Json.Net serializer to output the .Json
property directly without serializing - while serializing the other properties?有没有办法“告诉” Json.Net 序列化器直接输出
.Json
属性而不序列化 - 同时序列化其他属性?
You could make a JsonConverter
to write the raw value of the string property to the output without changing it.您可以使用
JsonConverter
将字符串属性的原始值写入输出而不更改它。 You take responsibility for ensuring the string has valid JSON or else the resulting output will not be valid JSON either.您负责确保字符串具有有效的 JSON,否则结果输出也不是有效的 JSON。
Here is what the converter might look like:以下是转换器的外观:
class RawJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(string));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// write value directly to output; assumes string is already JSON
writer.WriteRawValue((string)value);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// convert parsed JSON back to string
return JToken.Load(reader).ToString(Formatting.None);
}
}
To use it, mark your JSON property with a [JsonConverter]
attribute like this:要使用它,请使用
[JsonConverter]
属性标记您的 JSON 属性,如下所示:
class Foo
{
...
[JsonConverter(typeof(RawJsonConverter))]
public string YourJsonProperty { get; set; }
...
}
Here is a demo: https://dotnetfiddle.net/BsTLO8这是一个演示: https : //dotnetfiddle.net/BsTLO8
Assuming you have a structure like this for serializing: 假设您有一个这样的结构用于序列化:
public class Record
{
[JsonProperty("id")]
public int Id
{
get;
set;
}
[JsonProperty("json")]
[JsonConverter(typeof(SpecialJsonConverter))]
public string Json
{
get;
set;
}
}
And you use code like this for serialization: 你使用这样的代码进行序列化:
var data = new []
{
new Record() { Id=1, Json = "{\"property\":\"data\"}" },
new Record() { Id=2, Json = "{\"property\":\"data2\", \"property2\":[1, 2, 3]}" }
};
var serialized = JsonConvert.SerializeObject(data);
Console.WriteLine(serialized);
All you need is to write a proper converter for the Json property. 您只需要为Json属性编写适当的转换器。 Luckily there is a method WriteToken in the JsonWriter class that could serve our needs:
幸运的是, JsonWriter类中有一个方法WriteToken可以满足我们的需求:
public sealed class SpecialJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var reader = new JsonTextReader(new StringReader(value.ToString()));
writer.WriteToken(reader);
}
}
Based on answer by Alex and comment by Shahin, I improved the converter a bit, and also implemented the reader to work also the other way (parse back from JToken to the string property): 基于Alex的回答和Shahin的评论,我对转换器进行了一些改进,并且还实现了读取器以另一种方式工作(从JToken解析回字符串属性):
public sealed class RawDataJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var tokenReader = reader as JTokenReader;
var data = tokenReader.CurrentToken.ToString(Formatting.None);
return data;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteToken(JsonToken.Raw, value);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.