[英]Serialize an object directly to a JObject instead of to a string in json.net
[英]How to serialize a JObject the same way as an object with Json.NET?
如何控制JObject到字符串的序列化?
我有一些返回JObject的API,我通常會應用一些更改並保留或返回它們。 我想避免持久化null屬性並應用一些額外的格式,但JsonConvert似乎完全忽略我的設置。
以下是問題的示例:
// startup.cs has the following
services.AddMvc().AddJsonOptions(o =>
{
o.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});
public class SampleController : Controller
{
JsonSerializerSettings _settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
};
[HttpPost]
[Route("object")]
public object PostObject([FromBody] SomeObject data)
{
return JsonConvert.SerializeObject(data, _settings);
}
[HttpPost]
[Route("jobject")]
public object PostJObject([FromBody] JObject data)
{
return JsonConvert.SerializeObject(data, _settings);
}
public class SomeObject
{
public string Foo { get; set; }
public string Bar { get; set; }
}
}
發布{ "Foo": "Foo", "Bar": null }
:
/object
返回{"Foo":"Foo"}
/jobject
返回{"Foo":"Foo","Bar":null}
我希望JObject方法返回相同的輸出json,就像我使用對象一樣。 如何在不創建助手的情況下實現這一目標? 有沒有辦法使用相同的設置序列化JObject?
我能夠做到這一點的唯一方法是首先將JObject
轉換為string
,然后將該字符串反序列化為ExpandoObject
(不要反序列化為object
因為你將返回一個JObject
)。 ExpandoObject
就像一個字典,它將使JsonConvert
實際調用配置的名稱案例策略。 我不確定為什么Newtonsoft.Json的作者沒有像他們為字典類型那樣處理JObject類型,但至少這項工作是有效的。
例:
// Construct a JObject.
var jObject = JObject.Parse("{ SomeName: \"Some value\" }");
// Deserialize the object into an ExpandoObject (don't use object, because you will get a JObject).
var payload = JsonConvert.DeserializeObject<ExpandoObject>(jObject.ToString());
// Now you can serialize the object using any serializer settings you like.
var json = JsonConvert.SerializeObject(payload, new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy
{
// Important! Make sure to set this to true, since an ExpandoObject is like a dictionary.
ProcessDictionaryKeys = true,
}
}
}
);
Console.WriteLine(json); // Outputs: {"someName":"Some value"}
我在這里使用ExpandoObject
獲取技巧:使用JSON.Net進行JObject和CamelCase轉換
與NewtonSoft框架完美集成的解決方案是提供一個尊重NamingStrategy
的自定義JObject轉換器。
public class JObjectNamingStrategyConverter : JsonConverter<JObject> {
private NamingStrategy NamingStrategy { get; }
public JObjectNamingStrategyConverter (NamingStrategy strategy) {
if (strategy == null) {
throw new ArgumentNullException (nameof (strategy));
}
NamingStrategy = strategy;
}
public override void WriteJson (JsonWriter writer, JObject value, JsonSerializer serializer) {
writer.WriteStartObject ();
foreach (JProperty property in value.Properties ()) {
var name = NamingStrategy.GetPropertyName (property.Name, false);
writer.WritePropertyName (name);
serializer.Serialize (writer, property.Value);
}
writer.WriteEndObject ();
}
public override JObject ReadJson (JsonReader reader, Type objectType, JObject existingValue, bool hasExistingValue, JsonSerializer serializer) {
throw new NotImplementedException ();
}
}
var snakeNameStrategy = new SnakeCaseNamingStrategy ();
var jsonSnakeSettings = new JsonSerializerSettings {
Formatting = Formatting.Indented,
Converters = new [] { new JObjectNamingStrategyConverter (snakeNameStrategy) },
ContractResolver = new DefaultContractResolver {
NamingStrategy = snakeNameStrategy
},
};
var json = JsonConvert.SerializeObject (obj, jsonSnakeSettings);
你可以在GitHub上找到一個正常工作的PoC。
當一個JObject
被序列化時,它的原始JSON被寫入。 JsonSerializerSettings
不影響其編寫的JSON。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.