Search code examples
c#asp.net-coreappsettingsasp.net-core-configuration

Is it possible to store and retrieve a Type in appsettings?


Is it possible to store a value of type Type in appsettings? (Also, that is a seriously hard question to search!)

I have a class like this, that I want to serialize and store in appsettings:

class MyClass{
    public Type StoredType {get; set;}
    public string Name {get; set;}
}

I have serialized the object

var obj = new MyClass{
    Name = "A String",
    StoredType = typeof(String)
};

var serialized = JsonConvert.SerializeObject(obj);

and stored it in appsettings:

"StoredClass" : {
    "StoredType" : "System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
    "Name" :  "A String"
}

When I try to load the object from the configuration, the Name field is populated, but StoredType is always null.

var configVal = _configuration.GetValue<MyClass>("StoredClass");

Assert.Equal(configVal.Name, "A String"); //passes
Assert.Equal(configVal.StoredType, typeof(String)); //fails
Assert.NotNull(configVal.StoredType); //fails

UPDATE: If I deserialize with Newtonsoft, it works, but configuration still doesn't.

var deserialized = JsonConvert.DeserializeObject<MyClass>(serialized);

Assert.Equal(configVal.Name, "A String"); //passes
Assert.Equal(configVal.StoredType, typeof(String)); //passes
Assert.NotNull(configVal.StoredType); //passes

CONCLUSION: @Sam Axe has a solution that works, and I ended up using it. I believe the reason for the problem is that Type is actually an abstract class. When we work with Type in code, the instance is usually a RuntimeType, which is a private class in the System namespace. So, it seems Newtonsoft is doing some trickery to deserialize this, but the JSON parser used by the Configuration library is not. It makes sense when you consider you can't actually deserialize a string to an abstract class.


Solution

  • You are outputting a string in the serialized text. You will need some method of reconstituting the string into a Type. There are many many methods of doing this. Here's a quick and dirty method:

    public class MyClass {
        private Type _myType = null;
    
        [JsonIgnore]
        public Type MyType {get { return _myType; }   set { _myType = value; } }
    
        public String StoredType {  
            get { return _myType.ToString(); }     
            set { _myType = Activator.CreateInstance(value); }
        }
    
        public string Name { get;set; }
    }