简体   繁体   中英

C#: Create dynamic JSON string based on properties in a class with Newtonsoft.Json package?

I have this class for building strings:

public class WebSocketMessageBuilder
{
    private readonly string _eventName;
    private readonly Dictionary<string, string> _eventData;

    public WebSocketMessageBuilder(string eventName)
    {
        _eventName = eventName;
    }

    public void AddData(string key, string value) => _eventData[key] = value;

    public string ToJson()
    {
        return @"";
    }
}

I would like to produce JSON strings like:

{
    "event_name": "testing1",
    "event_data": {
        "key1": "value1",
        "key2": "value2"
    }
}

This string could be created like:

var wsMessage = new WebSocketMessageBuilder("testing1");
wsMessage.AddData("key1", "value2");
wsMessage.AddData("key1", "value2");

Console.WriteLine(wsMessage.ToJson());

How would I finish off the ToJson method? The documentation showed me some cool stuff, but nothing that helped me do this?

I have tried this, but it seems to just give me my class name back?

return new JObject {["event_name"] = _eventName, ["event_data"] = JsonConvert.SerializeObject(_eventData)}.ToString();

You can use the following way to serialize the object,

using Newtonsoft.Json;  // This goes with the other using statements on top.

public string ToJson()
{
    return JsonConvert.SerializeObject(this, Formatting.Indented);
}

this is the reference to the object itself. Formatting.Indented will produce the serialized version with the proper indentation.

To make it work with the private properties, use the attribute [JsonProperty] above the private properties. See documentation here

Excerpt:

By default a type's properties are serialized in opt-out mode. What that means is that all public fields and properties with getters are automatically serialized to JSON, and fields and properties that shouldn't be serialized are opted-out by placing JsonIgnoreAttribute on them. To serialize private members, the JsonPropertyAttribute can be placed on private fields and properties

public class test
{
    [JsonProperty]
    private string prop1 { get; set; }
    [JsonProperty("property_name")]
    private string prop2 { get; set; }
}

Note: When I ran your code, it produced errors with the dictionary because it was not initizlied, in your constructor, you should add the initialization as well,

public WebSocketMessageBuilder(string eventName)
{
    _eventName = eventName;
    _eventData = new Dictionary<string, string>(); // this will help with NRE errors.
}
//using System.Text.Json;

public string ToJson()
{
    return JsonSerializer.Serialize(this);
}

---- Update: ----

With the following code, I am getting exactly what you expect.

Note that Fields are converted to properties with the private set (this is important) and dictionary added to the Constructor.

public class WebSocketMessageBuilder
{
    public string event_name { get; private set; }
    public Dictionary<string, string> event_data { get; private set; }

    public WebSocketMessageBuilder(string eventName, Dictionary<string, string> eventData)
    {
        event_name = eventName;
        event_data = eventData;
    }

    public string ToJson()
    {
        return JsonSerializer.Serialize(this);
    }
}

How to Call it?: :

    var eventData = new Dictionary<string, string>();
    eventData.Add("key1", "value1");
    eventData.Add("key2", "value2");

    var wsMessage = new WebSocketMessageBuilder("testing1", eventData);

    var jsonResult = wsMessage.ToJson();

Result I am getting

{"event_name":"testing1","event_data":{"key1":"value1","key2":"value2"}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM