클래스를 JSON 문자열로 직렬화하려고합니다. 첫째, 내 실제 코드 :
// Note that this class is inside a PCL
public class CommunicationMessage {
public String Key { get; set; }
public String Value { get; set; }
public List<CommunicationMessage> Childs { get; set; }
}
다음과 같이 xml로 변환 할 수있는 템플릿입니다.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myproject>
<communicationmessage>
<header>
<participantid>1</participantid>
<deviceid>54325</deviceid>
<devicetype>Smartphone Samsung 4500</devicetype>
<timestamp>3456453445</timestamp>
<location>343-5343-64353</location>
<networkid>32</networkid>
<messageid>4003</messageid>
</header>
<data>
</data>
</communicationmessage>
</myproject>
보시다시피 Key 변수 는 이름이 communicationmessage 인 Xml-Element입니다 .
이제 U는 템플릿에 beeing는 JSON 문자열로 변환 원하지만 확실히 내가 요소 대신 얻을 communicationmessage 요소 "키": "communicationmessage" . "mymessage": "This is a test" 와 같은 요소에 대해 무언가를 얻을 수있는 방법이 있습니까? 여기서 "mymessage"는 키이고 "This is a test"는 값입니까?
도움을 주셔서 감사합니다
이 코드로 해결했습니다.
public class CommunicationMessageJSONSerializer : JsonConverter {
/// <summary>
/// Used to
/// </summary>
/// <param name="objectType"></param>
/// <returns></returns>
public override bool CanConvert(Type objectType) {
return typeof(CommunicationMessage).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
}
/// <summary>
/// Deserializes the JSON string
/// </summary>
/// <param name="reader"></param>
/// <param name="objectType"></param>
/// <param name="existingValue"></param>
/// <param name="serializer"></param>
/// <returns></returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
// Load the JSON object from the reader
JObject jsonObject = JObject.Load(reader);
// Get the First Token
JToken token = jsonObject.Children().First();
// The deserialized message
CommunicationMessage msg = ReadJSON(token);
return msg;
}
/// <summary>
/// This is the base method when deserializing a JSON string
/// </summary>
/// <param name="token"></param>
/// <returns>The root CommunicationMessage</returns>
private CommunicationMessage ReadJSON(JToken token) {
CommunicationMessage root = new CommunicationMessage();
if (token is JProperty) {
if (token.First is JValue) {
root.Key = ((JProperty)token).Name;
root.Value = (string)((JProperty)token).Value;
} else {
root.Key = ((JProperty)token).Name;
foreach (JToken child in token.Children()) {
ReadRecursive(child, ref root);
}
}
} else {
foreach (JToken child in token.Children()) {
ReadRecursive(child, ref root);
}
}
return root;
}
/// <summary>
/// This is the recursive method when deserializing a JSON string
/// </summary>
/// <param name="token"></param>
/// <param name="root">The root of the coming messages</param>
private void ReadRecursive(JToken token, ref CommunicationMessage root) {
if (token is JProperty) {
CommunicationMessage msg = new CommunicationMessage();
if (token.First is JValue) {
msg.Key = ((JProperty)token).Name;
msg.Value = (string)((JProperty)token).Value;
} else {
msg.Key = ((JProperty)token).Name;
foreach (JToken child in token.Children()) {
ReadRecursive(child, ref msg);
}
}
root.Childs.Add(msg);
} else {
foreach (JToken child in token.Children()) {
ReadRecursive(child, ref root);
}
}
}
/// <summary>
/// Serializes a CommuicationMessage to a JSON string
/// </summary>
/// <param name="writer"></param>
/// <param name="value"></param>
/// <param name="serializer"></param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
var msg = value as CommunicationMessage;
WriteRecoursive(writer, msg, serializer);
}
/// <summary>
/// This is the recursive method for serializing
/// </summary>
/// <param name="writer"></param>
/// <param name="msg"></param>
/// <param name="serializer"></param>
private void WriteRecoursive(JsonWriter writer, CommunicationMessage msg, JsonSerializer serializer) {
writer.WriteStartObject();
writer.Formatting = Formatting.Indented;
writer.WritePropertyName(msg.Key);
if (msg.Childs.Count > 0) {
writer.WriteStartArray();
foreach (CommunicationMessage child in msg.Childs) {
WriteRecoursive(writer, child, serializer);
}
writer.WriteEndArray();
} else {
writer.WriteValue(msg.Value);
}
writer.WriteEndObject();
}
}
코드를 개선 할 아이디어가 있으면 알려주세요. 솔루션을 계속 업데이트하겠습니다.
도와 주셔서 감사합니다
사용자 지정 serialization을 사용 하거나 ISerializable을 구현하는 것 외에 다음을 수행 할 수 있습니다. 그러나이 메서드에는 모든 속성을 이와 같이 래핑해야하는 단점이 있습니다. 그렇지 않으면 속성이 직렬화되지 않습니다. 이 빠르고 더러운 방법은 작은 클래스에 적합하지만 더 복잡한 클래스를 만드는 경우 ISerializable을 구현하는 것이 좋습니다.
public class CommunicationMessage : Dictionary<string, object>
{
//this "hack" exposes the "Child" as a List
public List<CommunicationMessage> Childs
{
get {
return (List<CommunicationMessage>)this["Childs"];
}
set
{
this["Childs"] = value;
}
}
public CommunicationMessage()
{
this["Childs"] = new List<CommunicationMessage>();
}
}
용법:
var m = new CommunicationMessage();
m["mymessage"] = "This is a test";
출력은 다음과 같아야합니다.
{
"Childs": [],
"mymessage": "This is a test"
}
대체 ISerializable 구현 :
public class CommunicationMessage:ISerializable
{
public String Key { get; set; }
public String Value { get; set; }
public List<CommunicationMessage> Childs { get; set; }
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(Key, Value);
PropertyInfo[] pi=this.GetType().GetProperties();
foreach(var p in pi)
{
if (p.Name == "Key" || p.Name == "Value")
continue;
info.AddValue(p.Name, p.GetValue(this));
}
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다