How to fetch config file details for specific environment - c#

I have a appSetting.json file which contains data segregatted by different test environments. I want to fetch data only of specific environment. I the below code I am getting null value in envConfig.
public static EnvironmentData GetConfigData()
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appSetting.json").Build();
var env = Environment.GetEnvironmentVariable("Environment"); //QA
var appSetting = config.Get<AppSetting>();
EnvironmentData envConfig = appSetting.appData
.Where(x => x.environment == env).Select(x => x.environmentData) as EnvironmentData;
return envConfig;
}
AppSettings.cs
public class AppData
{
public string environment { get; set; }
public EnvironmentData environmentData { get; set; }
}
public class EnvironmentData
{
public string baseUrl { get; set; }
public string conn_string { get; set; }
}
public class AppSetting
{
public List<AppData> appData { get; set; }
}
appSetting.json
{
"appData":[
{
"environment":"QA",
"environmentData":{
"baseUrl":"QA_Base_URL",
"conn_string":"QA dummy string"
}
},
{
"environment":"UAT",
"environmentData":{
"baseUrl":"UAT_Base_URL",
"conn_string":"UAT dummy string"
}
}
]
}
In the above code I am able to fetch all the json data into appsetting variable. I want to get data according to my environment which is set in environmnet variable.

Related

Returning List with Children in ASP.NET CORE with firebase

I am trying to do a get all with an ASP.NET Core project that uses this firebase library and I can't seem to return the children nested in an object. I have 3 classes: Route, Via & Waypoints(Serves as a bridge for JSON Deserialization).
public class Route
{
public string Route_ID { get; set; }
public string Destination { get; set; }
public string Origin { get; set; }
public Waypoints Stops { get; set; }
public Route()
{
}
}
public class Via
{
public string Via_ID { get; set; }
public string Route_ID { get; set; }
public int Seq_Number { get; set; }
public string Coordonnees { get; set; }
public string Description { get; set; }
public Via()
{
}
}
public class Waypoints
{
public List<Via> Vias;
public Waypoints()
{
}
}
In my GET method I go Fetch everything from my Routes and want to return it as one JSON List containing all my routes along with their waypoints but it only returns an empty list of Waypoints:
[HttpGet]
public async Task<IEnumerable<Route>> Get()
{
List<Route> routes = (await firebaseClient
.Child("routes")
.OrderByKey()
.OnceAsync<Route>())
.Select(item =>
new Route
{
Route_ID = item.Key,
Origin = item.Object.Origin,
Destination = item.Object.Destination,
Waypoints = item.Object.Waypoints
}).ToList();
foreach (Route route in routes)
{
List<Via> vias = (await firebaseClient
.Child("routes")
.Child(route.Route_ID)
.Child("Waypoints")
.OrderByKey()
.OnceAsync<Via>())
.Select(waypoint =>
new Via
{
Via_ID = waypoint.Key,
Route_ID = waypoint.Object.Route_ID,
Coordonnees = waypoint.Object.Coordonnees,
Seq_Number = waypoint.Object.Seq_Number,
Description = waypoint.Object.Description
}).ToList();
if(vias.Count > 0)
{
route.Stops.Vias = vias;
}
}
return routes;
}
My data structure:
{
"routes" : {
"987321": {
"Destination": "13.13;-12.34",
"Origin": "12.12;-12.12",
"Route_ID": "987321",
"Waypoints": {
"4d5e6f": {
"coordonnees": "45.8;-74.7",
"description": "Description",
"route_id": "987321",
"seq_number": 2,
"via_id": "4d5e6f"
},
"111222": {
"coordonnees": "45.8;-74.7",
"description": "Description",
"route_id": "987321",
"seq_number": 1,
"via_id": "111222"
}
}
}
}
}
And finally my call result:
[
{
"route_ID": "987321",
"destination": "13.13;-12.34",
"origin": "12.12;-12.12",
"waypoints": {}
}
]
It seems the Deserializing doesn't go further than the first layer of children. Is there any solution to this?
Thanks to Rena's suggestion, I figured out that the problem was located in my Waypoints bridging class that was missing a { get; set; }
Here is the change that was made to my class:
public class Waypoints
{
public List<Via> Vias { get; set; }
public Waypoints()
{
}
}

Accessing Json Array from appsettings using Options .NET C#

I've already searched, there are similar questions, but with JSON Array in answers they are using IConfigure in the controller. I can use IConfigure only in Startup.
I have this JSON Array in appsettings.json
{
"EmailList":[
{
"name":"John Algovich",
"email":"John.Algovich#mail.com"
},
{
"name":"Petr Algr",
"email":"Petr.Algr#mail.com"
},
{
"name":"Mathew Cena",
"email":"Mathew.Cena#mail.com"
}
]
}
EmailList.cs:
public class EmailAddress {
public string Name { get; set; }
public string Email { get; set; }
}
public class EmailList {
public List<EmailAddress> EmailArray { get; set; }
}
There is a lot of injections in Startup.cs, so I used the same code for mine:
services.Configure<EmailList>(Configuration.GetSection("EmailList"));
Controller:
public class DevController : Controller
{
private readonly EmailList _devEmailList;
private List<string> _emailList;
public DevController(
IOptions<EmailList> _devEmailList,
{
_devEmailList = devEmailList.Value;
_emailList = new List<string>();
}
}
public IActionResult Index()
{
var result = _devEmailList; // Returns null
var mailData2 = JsonConvert.DeserializeObject<EmailList>(_devEmailList.EmailArray.ToString()); // Returns null
}
Goal: How can get email adresses in Controller using Options and add it to the list?
Ok, so I was able to solve the problem:
I kept my appsettings.json the way it is with config classes.
I changed Startup code to this:
EmailInfo[] emails = Configuration.GetSection("EmailList").Get<EmailInfo[]>();
services.Configure<EmailList>(options => {options.EmailArray = emails.ToList();});
In my Controller:
This stays the same
public class DevController : Controller
{
private readonly EmailList _devEmailList;
private List<string> _emailList;
public DevController(
IOptions<EmailList> _devEmailList,
{
_devEmailList = devEmailList.Value;
_emailList = new List<string>();
}
}
Getting emails:
public IActionResult Index() {
var result = _udeEmailList.EmailArray;
foreach (var mailInfo in result)
{
emailsList.Add(mailInfo.Email);
}
}
what you are retrieving as your section is IEnumerable<EmailAddress> not EmailList. Read what you wrote, in your config there's no "EmailArray" definition.
You can add another level in your config (useful if you will have more things relative to email configuration in that section) or change the type to IEnumerable<EmailAddress> (not needed to be concretely IEnumerable, anything that implements it like an array or a list will work).
If you go for the first option you must do something like this:
In your config file...
{
"EmailConfig":{
"EmailList":[
{
"name":"John Algovich",
"email":"John.Algovich#mail.com"
},
{
"name":"Petr Algr",
"email":"Petr.Algr#mail.com"
},
{
"name":"Mathew Cena",
"email":"Mathew.Cena#mail.com"
}
]
//You can add here more properties
}
}
Your config classes:
public class EmailAddress
{
public string Name { get; set; }
public string Email { get; set; }
}
public class EmailConfig
{
public List<EmailAddress> EmailList { get; set; }
}
Your configuration:
services.Configure<EmailConfig>(Configuration.GetSection("EmailConfig"));
And the controller:
public class DevController : Controller
{
private readonly EmailConfig _mailConfig;
public DevController(IOptions<EmailConfig> mailConfig)
{
_mailConfig = mailConfig.Value;
}
public IActionResult Index()
{
var result = _mailConfig.EmailList;
}
}

IOptions not getting the values from appsettings.Development.json

I am trying to create a gateway api using net core. When I try to redirect the call using app.route :
app.Run(async (context) =>
{
using (var serviceScope = app.ApplicationServices.CreateScope())
{
var routing = serviceScope.ServiceProvider.GetService<IRoutingService>();
var content = await routing.RouteRequest(context.Request);
await context.Response.WriteAsync(await content.Content.ReadAsStringAsync());
content.Dispose();
// Seed the database.
}
});
... And RoutingService service starts like :
public class RoutingService : IRoutingService
{
private readonly RouteManagement _routeManagement;
static HttpClient _client = new HttpClient();
public RoutingService(IOptions<RouteManagement> routeManagement)
{
_routeManagement = routeManagement.Value;
}
...
.. I can not get the values from json file filled. The following is the json file :
{
"tokenManagement": {
"secret": "Any String used to sign and verify JWT Tokens, Replace this string with your own Secret",
"issuer": "threenine.co.uk",
"audience": "SampleAudience",
"accessExpiration": 30,
"refreshExpiration": 60
},
"routeManagement": {
"Routes": [
{
"Endpoint": "/coupons",
"Destination": {
"Uri": "http://localhost:30561/coupons/",
"RequiresAuthentication": "true"
}
},
{
"Endpoint": "/songs",
"Destination": {
"Uri": "http://localhost:8091/songs/",
"RequiresAuthentication": "false"
}
}
]
}
}
Am I doing smth wrong? The following is the class RouteManagement
public class RouteManagement
{
public List<Routes> Routes { get; set; }
}
public class Routes
{
public string Endpoint { get; set; }
public Routes.DestinationManagement Destination { get; set; }
public class DestinationManagement
{
private DestinationManagement()
{
Uri = "/";
RequiresAuthentication = false;
}
public string Uri { get; set; }
public bool RequiresAuthentication { get; set; }
}
}
Follow steps below to resolve your issue:
Register RouteManagement
services.Configure<RouteManagement>(Configuration.GetSection("routeManagement"));
You need to make DestinationManagement() public, otherwise, it will fail to initialize the DestinationManagement
public class RouteManagement
{
public List<Routes> Routes { get; set; }
}
public class Routes
{
public string Endpoint { get; set; }
public Routes.DestinationManagement Destination { get; set; }
public class DestinationManagement
{
public DestinationManagement()
{
Uri = "/";
RequiresAuthentication = false;
}
public string Uri { get; set; }
public bool RequiresAuthentication { get; set; }
}
}
Have you registered the configuration instance which RouteManagement binds against in ConfigureServices method ?
services.Configure<RouteManagement>(Configuration);

AutoMapper to map a child list object

I'm using an generic method to map two classes using Automapper
My generic methods
public class AutoMapperConfiguration
{
public MapperConfiguration Configure<TSource, TDestination>() where TSource:class where TDestination:class
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<ClientMappingProfile<TSource,TDestination>>();
});
return config;
}
}
ClientMappingProfile.cs
public class ClientMappingProfile<TSource,TDestination>: Profile where TSource : class where TDestination:class
{
public ClientMappingProfile()
{
CreateMap<TSource, TDestination>().ReverseMap();
}
}
StudentDetailsViewModel.cs
public class StudentDetailsViewModel
{
public long ID { get; set; }
public string FirstName { get; set; }
public List<QualificationViewModel> listQualificationViewModel { get; set; }
}
QualificationViewModel.cs
public class QualificationViewModel
{
public long ID { get; set; }
public long StudentID { get; set; }
public string ExaminationPassed { get; set; }
}
StudentValueObject.cs
public class StudentValueObject
{
public long ID { get; set; }
public string FirstName { get; set; }
public List<StudentQualificationValueObject> listStudentQualificationValueObject { get; set; }
}
StudentQualificationValueObject.cs
public class StudentQualificationValueObject
{
public long ID { get; set; }
public long StudentID { get; set; }
public string ExaminationPassed { get; set; }
}
Usage
StudentValueObject studentValueObject = new StudentValueObject();
var config = new AutoMapperConfiguration().Configure<StudentValueObject, StudentDetailsViewModel>();
var iMapper = config.CreateMapper();
studentValueObject = iMapper.Map<StudentDetailsViewModel, StudentValueObject>(objStudentModel);
So, this works fine with Mapping StudentDetailsViewModel.cs with StudentValueObject.cs. But it silently fails to copy my child list objects which is List<QualificationViewModel> to List<StudentQualificationValueObject>. The child list object always seems to be null. I'm pretty newbie to AutoMapper. I need some help as to know where am I going wrong or what need to be added/fixed to my generic method, so that the child list object gets copied to with Parent object.
Update -
Currently I'm doing it using below code and its working properly but I'm confused is this the proper way of doing this.
StudentValueObject studentValueObject = new StudentValueObject();
var config = new AutoMapperConfiguration().Configure<StudentValueObject, StudentDetailsViewModel>();
var iMapper = config.CreateMapper();
studentValueObject = iMapper.Map<StudentDetailsViewModel, StudentValueObject>(objStudentModel);
config = new AutoMapperConfiguration().Configure<StudentQualificationValueObject, QualificationViewModel>();
iMapper = config.CreateMapper();
studentValueObject.listStudentQualificationValueObject = iMapper.Map<List<QualificationViewModel>, List<StudentQualificationValueObject>>(objStudentModel.listQualificationViewModel);
You have to map the list properties, cause they have different names in the given parent types and you have to add a mapping for the types used within both lists. Here is an working example for your code:
public class StudentsMappingProfile : Profile
{
public StudentsMappingProfile()
{
CreateMap<StudentValueObject, StudentDetailsViewModel>()
.ForMember(viewModel => viewModel.listQualificationViewModel, conf => conf.MapFrom(value => value.listStudentQualificationValueObject));
CreateMap<StudentQualificationValueObject, QualificationViewModel>();
}
}
public class Program
{
public static void Main()
{
var config = new MapperConfiguration(cfg => cfg.AddProfile<StudentsMappingProfile>());
var mapper = config.CreateMapper();
var source = new StudentValueObject { ID = 73, FirstName = "Hello", listStudentQualificationValueObject = new List<StudentQualificationValueObject> { new StudentQualificationValueObject { ID = 42, StudentID = 17, ExaminationPassed = "World" } } };
var destination = mapper.Map<StudentDetailsViewModel>(source);
Console.ReadKey();
}
}

Is there a built in way to serialize array configuration values?

I'm on a new ASP.NET 5 project.
I'm trying to read an array value, stored in my config.json file, that looks like this:
{
"AppSettings": {
"SiteTitle": "MyProject",
"Tenants": {
"ReservedSubdomains": ["www", "info", "admin"]
}
},
"Data": {
"DefaultConnection": {
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-MyProject....."
}
}
}
How do I access this from my C# code?
At least with beta4 arrays aren't supported in config.json. See ASP.NET issue 620. But you could use the following config.json:
"AppSettings": {
"SiteTitle": "MyProject",
"Tenants": {
"ReservedSubdomains": "www, info, admin"
}
}
and map it to a class like this:
public class AppSettings
{
public string SiteTitle { get; set; }
public AppSettingsTenants Tenants { get; set; } = new AppSettingsTenants();
}
public class AppSettingsTenants
{
public string ReservedSubdomains { get; set; }
public List<string> ReservedSubdomainList
{
get { return !string.IsNullOrEmpty(ReservedSubdomains) ? ReservedSubdomains.Split(',').ToList() : new List<string>(); }
}
}
This can then be injected into a controller:
public class MyController : Controller
{
private readonly AppSettings _appSettings;
public MyController(IOptions<AppSettings> appSettings)
{
_appSettings = appSettings.Options;
}

Categories