0

I have a static class, example:

public static Config
{
    public static string ServerIP;
    ...
}

I made this static, because it can be easily accessed across the entire application.

The problem now is, how can I serialize / deserialize it? Because these configuration will change and using might modify the value in the json file.

s k
  • 4,342
  • 3
  • 42
  • 61
  • Does this answer your question? [Serialize a Static Class?](https://stackoverflow.com/questions/1293496/serialize-a-static-class) – OfirD Feb 24 '20 at 11:26
  • @HeyJude, Yes and No. Yes because it mentioned that static class is not serializable. No is because the solution (using reflection) provided does work for Xml, but is not possible for Json serializer. – s k Feb 24 '20 at 11:45
  • @HeyJude. Ability to instantiate has nothing to do with serialization. If I were to write my own serializer today, I am sure there isn't any difficulties in getting one done for a static class. – s k Feb 24 '20 at 12:27
  • Google **Serialization** please. – s k Feb 24 '20 at 12:36
  • An easy workaround I found was to remove the static modifier from the class, but leave all members as static and put the [JsonProperty] tag above each member. Then just instantiate the class in the JsonConvert.SerializeObject argument – user4779 Nov 22 '22 at 05:36

2 Answers2

1

Neither System.Text.Json nor Newtonsoft.Json support serialization of static classes. So while you can't serialize the class directly, you can serialize its members.

If you can use Newtonsoft.Json, then you can shim something like this at least for deserialization, and something similar for serialization:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

static class Config
{
    public static string ServerIP = string.Empty;
}

static void DeserializeStaticClass(string json, Type staticClassType)
{
    if (!staticClassType.IsClass)
        throw new ArgumentException("Type must be a class", nameof(staticClassType));

    if (!staticClassType.IsAbstract || !staticClassType.IsSealed)
        throw new ArgumentException("Type must be static", nameof(staticClassType));

    var document = JObject.Parse(json);
    var classFields = staticClassType.GetFields(BindingFlags.Public | BindingFlags.Static);

    foreach (var field in classFields)
    {
        var documentField = document[field.Name];
        if (documentField == null)
            throw new JsonSerializationException($"Not found in JSON: {field.Name}");
        field.SetValue(null, documentField.ToObject(field.FieldType));
    }
}

...

DeserializeStaticClass("{\"ServerIP\": \"localhost\"}", typeof(Config));

If you need to customize serialization of nested members, you can pass a JsonSerializer to documentField.ToObject.

Jeff
  • 7,504
  • 3
  • 25
  • 34
  • Tested and it works, not very easy to use, but seems like the only solution for now. Thx – s k Feb 26 '20 at 04:43
1

I realize this Q is a bit old, but here's what I do...

In my static class, I make a method that materializes the class' data and returns it as an object. Then this can be used to pass in to NewtonSoft or whatever other serialization you use.

As example, here is my method in my static (INI) class:

public static dynamic Materialize() {
    return new {
        Web = Web, 
        Client = Client, 
        Logging = Logging
    };
}

and then I can easily call this and effectively serialize my class, like so:

if(Arguments.Verbose) {
    var json = JsonConvert.SerializeObject(INI.Materialize(), Formatting.Indented);
    Logging.Log($"INI Configuration:\n{json}");
}
eidylon
  • 7,068
  • 20
  • 75
  • 118