[英]Convert C# class to Json with customized structure
我們有如下的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是與value一起使用的 。 對於某些選定的屬性,我們需要像這樣序列化。 另外,我們需要從JSON讀取並反序列化到類中。 我們是否可以通過裝飾元素來遵循通用的最佳方法,以便獲得此結果?
當您用json.net標記問題時,可以通過對序列化時應嵌套在{"value" : ... }
對象內的“ selected JsonConverter
”應用自定義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);
筆記:
由於轉換器的目的是使用所述屬性來直接應用[JsonConverter(typeof(NestedValueConverter<...>))]
或[JsonProperty(ItemConverterType = typeof(NestedValueConverter<...>))]
, CanConvert
,其僅稱為當轉換器包含在設置中時,未實現。
如果您需要嵌套非字符串值,則該轉換器是通用的。
樣品在這里擺弄。
這里的前綴標題也是一個類而不是字符串。 在這里,您的班級要看起來像這樣。
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;}
}
將Newtonsoft.json libraby文件安裝到您的項目:-> 在Tools NuGet Package中打開Package Manager控制台並將其粘貼,然后按Enter 。
Install-Package Newtonsoft.Json -Version 12.0.1
將類轉換為Json:
string output = JsonConvert.SerializeObject(classname);
將Json轉換為Object:
這里的object表示一個Class
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;
}
您可以通過以下方法使用此方法來實現輸出:
string jsonData = getJsonFromClass(Prefix);
string JsonString = "<here your json string>";
Prefix getObjectFromJson = getObjectFromJson<Prefix>(JsonString);
就這樣 ..
希望對您有幫助。
您可以通過更改模型來實現此目的,例如:
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>();
您需要為您的對象編寫自定義序列化程序。 這是一個示例,展示了如何通過擴展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"
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.