I want to use different property names for configuration, when loading the configuration from a JSON file.
public class MinioConfiguration
{
[DataMember(Name = "MINIO_ENDPOINT")]
public string Endpoint { get; set; }
[DataMember(Name = "MINIO_ACCESS_KEY")]
public string AccessKey { get; set; }
[DataMember(Name = "MINIO_SECRET_KEY")]
public string SecretKey { get; set; }
}
Neither DataMember
nor JsonProperty
work. Is there a possibility to achieve it?
In JSON, the “keys” must always be strings. Each of these pairs is conventionally referred to as a “property”.
DeserializeObject Method. Deserializes the JSON to a . NET object.
This is unfortunately not possible. The responsible components here are the JSON configuration provider (Microsoft.Extensions.Configuration.Json
) and the configuration binder (Microsoft.Extensions.Configuration.Binder
). The former is responsible for loading the JSON file into an IConfiguration
, while the latter’s job is to map an IConfiguration
into a type.
The configuration binder however is source agnostic, so it does not care where the configuration came from, whether that being JSON, an in-memory configuration or environment variables. So the binder, by design, cannot look for source-specific attributes on the target type.
On the other hand, configurations are not guaranteed to be bound to any type, so the configuration provider needs to work consistently regardless of whether it binds to a type or not. So the JSON provider follows its own conventions to map JSON properties to configuration keys.
Since both components run independently—the binder running even explicitly on the IConfiguration
object, so it runs much later than the actual configuration parsing process—they cannot communicate and share information. So it’s simply not possible for the JSON configuration provider to access the information, the binder much later gets about the target type. As such, you simply cannot change the configuration names.
However, I would argue that this is not something that should be done anyway. The configuration is a very application-specific thing, but if you want to use different keys that looks like you want to use a configuration file that is not necessarily owned by the application. I would recommend against this approach and rather use an application-specific configuration file.
If you need to reuse that configuration file, you could always write your own configuration provider for that specific type. Writing a configuration provider is not that difficult, especially when you are going to restrict it to a very specific format anyway.
In case someone run into this.
Here's old hack for it:
public class ServiceConfig
{
private string web_internal
{
// Note it does not work without this noop getter
get => "it's hack for Microsoft.Configuration.Binder";
set => WebInternal = value;
}
public string WebInternal { get; set; }
}
Then where you want to bind it
var serviceConfig = config.Get<ServiceConfig>(o => o.BindNonPublicProperties = true);
Though I think Microsoft should add support to override names.
It's not about that relations with ConfigurationSource
's, it's about ConfigurationBinder
itself - if it sees that property has DataMember
attribute then it should use it instead of property name for the key.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With