Problem with accentued char when reading appsettings.json with builder - c#

I am reading the configuration file appsettings.json with the builder;
var builder = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile(Path.Combine(Helper.jsonpath, "appsettings.json"));
Helper.config = builder.Build();
//same result : P�le emploi instead of Pôle emploi
var tt = Helper.config.GetSection("partooApi:types:APE").GetValue<string>("title");
var ttt = Helper.config["partooApi:types:APE:title"];
var tttt = Helper.config.GetSection("partooApi:types:APE:title").Get<string>();
i have the result P�le emploi instead of Pôle emploi
my appsettings.json has nothing special:
"partooApi": {
"types": {
"APE": {
"title": "Pôle emploi",
"grpname": "Agences",
"grpid": 10661
}
:
I dont see options to encode, am i missing something in my code?

Have you checked if appsettings.json is saved as UTF-8 encoding?

Related

.NET 6.0 - retrieving string array from a specific appsettings.json file

I have two appsettings files in my project: appsettings.json and appsettings.Development.json. I have string arrays in both files: two developers' e-mails in the Development file and seven production e-mails in the main appsettings.json file.
appsettings.Development.json:
"Contacts": {
"Emails": [ "email1", "email2" ],
}
appsettings.json:
"Contacts": {
"Emails": [ "email3", "email4", "email5", "email6", "email7", "email8", "email9" ],
}
I have this setup in my Program.cs:
WebApplicationOptions opts = new WebApplicationOptions
{
ApplicationName = "WebServices",
EnvironmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
};
var builder = WebApplication.CreateBuilder(opts);
builder.Services.Configure<Contacts>(builder.Configuration.GetSection("Contacts"));
Then in my StoreDataService.cs:
private readonly Contacts _contactSettings;
public StoreDataService(IOptions<DatabaseSettings> dbSettings, IOptions<Contacts> contactSettings) : base(dbSettings)
{
_dbSettings = dbSettings.Value;
_contactSettings = contactSettings.Value;
string[] emailList = _contactSettings.Emails;
}
The problem is in my emailList array I'm getting back
[ "email1", "email2", "email5", "email6", "email7", "email8", "email9" ]
in both Development and Production. All other fields come back correctly between the two environments. Is there something special I'm needing to do for the string array?

How do I make my azure secrets read in Program.cs available to a controller?

anyone else encountered this - you read your secrets from an azure key vault (typically in Program.cs right? Like this:
.ConfigureAppConfiguration(builder =>
{
var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
var keyVaultEndpoint = configuration.GetSection("KeyVault").GetSection("KeyVaultEndpoint").Value);
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
builder.AddAzureKeyVault(keyVaultUrl, keyVaultClient, new DefaultKeyVaultSecretManager());
var secretValue = Task.Run(async () => await keyVaultClient.GetSecretAsync(keyVaultEndpoint, "SomeDatabasePassword")).Result.Value;
How do you use this secretValue somewhere else, for example in a controller?
Considering my appsettings looks like this:
{
"KeyVault": {
"SomeDatabasePassword": ""
}
}
typically empty because we don't want to be explicitly set here in appsettings. But in Program.cs I can read that element from secrets and (while still in Program.cs)
I can overwrite the appsettings key right? Like this:
configuration.GetSection("KeyVault").GetSection("SomeDatabasePassword").Value = secretValue;
However if I then try to read this value configuration.GetSection("KeyVault").GetSection("SomeDatabasePassword").Value from a controller, I still get an empty string.
Any ideas?

How to add custom headers in NSwag document using C# .NET CORE?

I am in need of adding custom headers, but cannot figure it out. I am trying to utilize the new services.AddOpenApiDocument() instead of the services.AddSwaggerDocument(). I want to add these custom headers on my whole API not just a single method or controller. I attempted to add an operation processor, but when I load up the swagger UI I receive the following error "😱 Could not render this component, see the console."
Here is my snippet within my ConfigureServices():
services.AddOpenApiDocument(document =>
{
...
// this works fine
document.OperationProcessors.Add(new OperationSecurityScopeProcessor("Bearer"));
document.DocumentProcessors.Add(new SecurityDefinitionAppender("Bearer", new SwaggerSecurityScheme
{
Type = SwaggerSecuritySchemeType.ApiKey,
Name = "Authorization",
In = SwaggerSecurityApiKeyLocation.Header
})
);
// this is the header i want to show up for all endpoints that is breaking
document.OperationProcessors.Add(new SampleHeaderOperationProcessor());
});
Here is my operation processor:
public class SampleHeaderOperationProcessor : IOperationProcessor
{
public Task<bool> ProcessAsync(OperationProcessorContext context)
{
context.OperationDescription.Operation.Parameters.Add(
new SwaggerParameter {
Name = "Sample",
Kind = SwaggerParameterKind.Header,
Type = NJsonSchema.JsonObjectType.String,
IsRequired = false,
Description = "This is a test header",
Default = "{{\"field1\": \"value1\", \"field2\": \"value2\"}}"
});
return Task.FromResult(true);
}
}
The only thing I have pertaining to this within my Configure():
app.UseSwagger();
app.UseSwaggerUi3();
Here is my error and the console log:
My error and console log
If it helps I'm using ASP .NET CORE 2.2 and NSwag.AspNetCore v12.1.0
Here's an example I've implemented in a project. For me here, it's working normally:
Implementation of the interface "IOperationProcessor":
using NSwag;
using NSwag.SwaggerGeneration.Processors;
using NSwag.SwaggerGeneration.Processors.Contexts;
using System.Threading.Tasks;
namespace api.mstiDFE._Helpers.Swagger
{
public class AddRequiredHeaderParameter : IOperationProcessor
{
public Task<bool> ProcessAsync(OperationProcessorContext context)
{
context.OperationDescription.Operation.Parameters.Add(
new SwaggerParameter
{
Name = "token",
Kind = SwaggerParameterKind.Header,
Type = NJsonSchema.JsonObjectType.String,
IsRequired = false,
Description = "Chave de acesso à API, fornecida pela RevendaCliente",
Default = "Default Value"
});
return Task.FromResult(true);
}
}
}
Reference in startup.cs:
internal static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
// Register the Swagger services
services.AddSwaggerDocument(config =>
{
// Adds the "token" parameter in the request header, to authorize access to the APIs
config.OperationProcessors.Add(new AddRequiredHeaderParameter());
config.PostProcess = document =>
{
document.Info.Version = "v1";
document.Info.Title = "Title ";
document.Info.Description = "API para geração de Documentos Fiscais Eletrônicos (DF-e) do projeto SPED";
document.Info.TermsOfService = "None";
document.Info.Contact = new NSwag.SwaggerContact
{
Name = "Name",
Email = "Email ",
Url = "Url "
};
document.Info.License = new NSwag.SwaggerLicense
{
Name = "Use under LICX",
Url = "https://example.com/license"
};
};
});
}
This finally worked for me. Solution directly from Rico Suter,
Try
Schema = new JsonSchema4 { Type = NJsonSchema.JsonObjectType.String }
instead of
Type = NJsonSchema.JsonObjectType.String
(I think Type is deprecated in OpenAPI 3)
A big thanks to the original answers on this thread.
I had to do a few small updates to the above answers due to NSwag updates.
The below works for me on versions (NSwag.Core: 13.1.2, NJsonSchema: 10.0.24):
context.OperationDescription.Operation.Parameters.Add(
new OpenApiParameter
{
Name = "HEADER_NAME",
Kind = OpenApiParameterKind.Header,
Schema = new JsonSchema { Type = JsonObjectType.String },
IsRequired = true,
Description = "Description",
Default = "Default Value"
});

How to deal with configuration in new format (appsettings.json) in a console app

Simply stupid question - but I've already spent an hours trying to find out how to read
{
"AppSettings": {
"param": "value",
}
}
this simple appsettings.json file from the console application in the proper way?
I've done till this moment
var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
Configuration = builder.Build();
var section = Configuration.GetSection("AppSettings");
and now I get stuck
Configuration["AppSettings:param"]

ServiceStack: Custom app settings not used in view

I'm getting along quite nicely with ServiceStack, but ran into an issue which I can't currently work round. In my Global.asax.cs Configure() method, I declare a database based AppSettings as follows:
// Create app settings, based on dictionary settings from central database
Dictionary<string, string> configSettings = null;
using (var db = container.Resolve<IDbConnectionFactory>().Open())
{
configSettings = db.Dictionary<string, string>(db.From<ConfigSetting>());
}
var dicSettings = new DictionarySettings(configSettings);
// Register app settings for injection
container.Register<IAppSettings>(dicSettings);
This works great in code in which the AppSettings is injected:
public class RemoteEmailValidator : IEmailValidator
{
public IAppSettings AppSettings { get; set; }
public bool ValidEmail(string email)
{
try
{
if (String.IsNullOrEmpty(email) || email.Length > 256)
{
return false;
}
RestClient client = new RestClient();
string baseURL = AppSettings.Get("MailgunAPIBaseURL", "");
if (String.IsNullOrEmpty(baseURL))
{
// If we can't check email in-depth, then it's OK
return true;
}
else
{
client.BaseUrl = new Uri(baseURL);
client.Authenticator =
new HttpBasicAuthenticator(AppSettings.Get("MailgunAPIUserName", ""),
AppSettings.Get("MailgunAPIPublicKey", ""));
RestRequest request = new RestRequest();
request.Resource = AppSettings.Get("MailgunAPIEmailValidationResource", "");
request.AddParameter("address", email);
var response = client.Execute(request);
dynamic content = DynamicJson.Deserialize(response.Content);
return content.is_valid == "true";
}
}
catch { } // Suppress any errors, because email validation is nice to have
return true;
}
}
The values are retrieved from the database as you'd expect. However, when I try accessing AppSettings from a view, the values are returned from the web.config. E.g. in my register.cshtml:
string maxHouseholdMembers = HostContext.AppSettings.Get("MaxMembersPerHousehold", "20");
the value wasn't varying based on the value from the database, but was varying based on updating web.config. So, is there any additional config I need to do, to get my view to use the custom AppSettings I created in the global.asax.cs Configure() method?
Found the answer while I was actually posting the question. Just needed to add an extra line in the Configure() method:
// Create app settings, based on dictionary settings from central database
Dictionary<string, string> configSettings = null;
using (var db = container.Resolve<IDbConnectionFactory>().Open())
{
configSettings = db.Dictionary<string, string>(db.From<ConfigSetting>());
}
var dicSettings = new DictionarySettings(configSettings);
AppSettings = dicSettings;
The final line (AppSettings = dicSettings) does the trick and overrides the standard AppSettings.

Categories

Resources