简体   繁体   中英

Is it possible to import a System.Type from an appsettings.json file in a .net core application?

I'm trying to import a System.Type as part of a settings object from my appsettings.json file. The rest of the object imports fine, but when I add a System.Type property to my settings object I get the following exception:

An exception of type 'System.InvalidOperationException' occurred in Microsoft.Extensions.Configuration.Binder.dll but was not handled in user code

Additional information: Failed to convert 'MyType' to type 'System.Type'.

My appsettings.json is similar to:

"Settings": {
  "Url": "some url",
  "Type: "MyType"
}

My Settings object looks like:

public class Settings
{
    public string Url {get; set;}
    public Type Type {get; set;}
}

My Startup.cs contains uses this to bind the Settings:

var foo = Configuration.GetSection("Settings").Get<Settings>(); // This is where the exception occurs.

Obviously the Configuration Binder is reading in MyType as a String and doesn't know how to convert it to a System.Type . Is it possible to do so at the binder level, or will I need to do some reflection to turn that string into a System.Type at the point where it's used?

It's possible now.

Tested on .net core 3.1 with the following NuGet packages:

StringToTypeConverter must be registered at application startup before any manipulations with configuration.

appsettings.json:

{
  "Settings": {
  "Url": "some URL",
  "Type": "System.String, mscorlib" /*Fully qualified type name*/
  }
}

Code:

class Program
{
    static void Main()
    {
        // Registration of StringToTypeConverter
        TypeDescriptor.AddAttributes(typeof(Type), new TypeConverterAttribute(typeof(StringToTypeConverter)));

        // Build configuration
        var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", false)
            .Build();

        var settings = configuration.GetSection("Settings").Get<Settings>();

        Console.WriteLine("Settings.Type: {0}", settings.Type);
    }

    public class Settings
    {
        public string Url { get; set; }
        public Type Type { get; set; }
    }

    internal class StringToTypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string stringValue)
            {
                return Type.GetType(stringValue);
            }
            return base.ConvertFrom(context, culture, value);
        }
    }
}

This is not currently supported. The Configuration libraries do not support pulling in Types from JSON documents.

I got around this by adding a secondary settings file and using Json.NET to import that specific configuration object.

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