Reputation: 205
I have a C# Object that I need its attribute values into its own json object. I'm struggling with how to do this dynamically. I have attributes in my C# class that have values and I need to make those attribute values the Key/Value pair in the json respectively.
public class TransHelper
{
public string Key { get; set; }
public string Translation { get; set; }
}
TransHelper j = new TransHelper { Key = "MyKeyValue",
Translation = "MyTranslationValue" };
// Need to be json like this
// json { MyKeyValue: MyTranslationValue }
How do I make the attribute values get inserted into a new object where j.Key value is the new Key and j.Translation is the new value? I can use newtonsoft or any json libraries out there, I am sure there is something simple I am missing here.
Upvotes: 1
Views: 960
Reputation: 74277
Here's a custom converter that should do the trick (assuming you're using Newtonsoft Json.Net):
using System;
using Newtonsoft.Json;
namespace ConsoleApp8
{
public class TransHelper
{
public string Key { get; set; }
public string Translation { get; set; }
}
public class MyBlob
{
public string Foo { get; set; }
public TransHelper Bar { get; set; }
}
public class TransHelperConverter : JsonConverter<TransHelper>
{
public override TransHelper ReadJson( JsonReader reader, Type objectType, TransHelper existingValue, bool hasExistingValue, JsonSerializer serializer )
{
string key = null;
string val = null;
TransHelper instance = null;
if ( reader.TokenType != JsonToken.Null )
{
if ( reader.TokenType != JsonToken.StartObject )
throw new JsonReaderException( $"Unexpected Token: ${reader.TokenType}" );
if ( !reader.Read() )
throw new JsonReaderException( $"Unexpected EOF in Json" );
if ( reader.TokenType != JsonToken.EndObject )
{
if ( reader.TokenType != JsonToken.PropertyName )
throw new JsonReaderException( $"Unexpected Token: ${reader.TokenType}" );
key = (string)reader.Value;
if ( !reader.Read() )
throw new JsonReaderException( $"Unexpected EOF in Json" );
if ( reader.TokenType != JsonToken.String )
throw new JsonReaderException( $"Unexpected Token: ${reader.TokenType}" );
val = (string)reader.Value;
if ( !reader.Read() )
throw new JsonReaderException( "Unexpected EOF in Json" );
}
if ( reader.TokenType != JsonToken.EndObject )
throw new JsonReaderException( $"Unexpected Token: ${reader.TokenType}" );
instance = new TransHelper
{
Key = key,
Translation = val,
};
}
return instance;
}
public override void WriteJson( JsonWriter writer, TransHelper value, JsonSerializer serializer )
{
writer.WriteStartObject();
writer.WritePropertyName( value.Key );
writer.WriteValue( value.Translation );
writer.WriteEndObject();
return;
}
}
class Program
{
static void Main( string[] argv )
{
string json = @"
{
""Foo"": ""foo-value"",
""Bar"": {
""source"": ""translated-value""
},
}".Trim();
TransHelperConverter converter = new TransHelperConverter();
MyBlob deserialized = JsonConvert.DeserializeObject<MyBlob>( json, converter );
string reserialized = JsonConvert.SerializeObject( deserialized, Formatting.Indented, converter );
return;
}
}
}
Upvotes: 1
Reputation: 6524
Its better to use containers like Dictionary with <Key, Value>
, then you can use Newtonsoft.Json
(better than JavaScriptSerializer
), the code will look like this:
JsonConvert.SerializeObject(dict);
example:
var foo = new Dictionary<string, string>();
foo.Add("key1", "value1");
foo.Add("key2", "value2");
foo.Add("key3", "value3");
foo.Add("key4", "value4");
Console.WriteLine(JsonConvert.SerializeObject(foo));
// outputs { "key1":"value1","key2":"value2","key3":"value3","key4":"value4"}
Upvotes: 1
Reputation: 51130
public class TransHelper
{
public string Key { get; set; }
public string Translation { get; set; }
}
public static void Main()
{
var myList = new List<TransHelper> {
new TransHelper { Key = "K1", Translation = "T1" },
new TransHelper { Key = "K2", Translation = "T2" },
new TransHelper { Key = "K3", Translation = "T3" }
};
var dict = myList.ToDictionary(t => t.Key, t => t.Translation);
//Serialize dict to Json using Newtonsoft.Json (JSON.Net) or Utf8Json libraries
}
Upvotes: 2
Reputation: 8382
The way I would do such thing is by implementing a custom JsonConverter
(doc).
There is this question on SO that can give more details on how to do it.
Here is one way to do this:
public class TransHelperConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var transHelperInst = value as TransHelper;
if(transHelperInst is null)
throw new ArgumentException();
// Creates the Json property.
var property = new JProperty(transHelperInst.Key, transHelperInst.Translation);
// Adds it the Json object.
var transHelperObject = new JObject();
transHelperObject.AddFirst(property);
// Writes the object.
transHelperObject.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
}
public override bool CanRead => false;
public override bool CanConvert(Type objectType)
{
return objectType == typeof(TransHelper);
}
}
Now, you can use this converter like this:
var serializedValue = JsonConvert.SerializeObject(new TransHelper {Key = "MyKeyValue", Translation = "MyTranslationValue"}, Formatting.Indented, new TransHelperConverter());
This will give you the following result:
{
"MyKeyValue": "MyTranslationValue"
}
Upvotes: 1
Reputation: 1198
I think you can implement the generic abstract JsonConverter from Json.NET class to achieve this.
Here's the converter implementation:
public class MySerializer : JsonConverter<TransHelper>
{
public override TransHelper ReadJson(JsonReader reader, Type objectType, TransHelper existingValue, bool hasExistingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, TransHelper value, JsonSerializer serializer)
{
if(value == null) return;
writer.WritePropertyName(value.Key);
writer.WriteValue(value.Translation);
}
}
Here's how you call it:
var j = new TransHelper
{
Key = "MyKeyValue",
Translation = "MyTranslationValue"
};
var jsonString = JsonConvert.SerializeObject(j, Newtonsoft.Json.Formatting.Indented, new MySerializer());
Upvotes: 1