I would like to create a settings class for Event Hubs as follows:
public class EventHubsOptions
{
public string Name { get; set; }
public string ConsumerGroup { get; set; }
public string ConnectionString { get; set; }
}
Which I would then configure with the following:
services.Configure< EventHubsOptions >( Configuration.GetSection( "EventHubs" ) );
But that means I need to write my appsettings file as follows:
"EventHubs": {
"Name": "EventHubName",
"ConsumerGroup": "consumergroup",
"ConnectionString": "xxx"
}
Is there a way that would allow me to put the connection string within the ConnectionsStrings section of the appsettings? Something like this:
{
"EventHubs": {
"Name": "EventHubName",
"ConsumerGroup": "consumergroup"
},
"ConnectionStrings": {
"DefaultConnection": "xxx",
"EventHubsConnection" : "xxx",
"StorageConnection": "xxx"
}
}
How would I configure the EventHubsOptions class during startup?
You can try this way -
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.Configure<EventHubsOptions>(Configuration.GetSection("EventHubs"));
// These are run after all Configure<TOptions>
services.PostConfigure<EventHubsOptions>(o =>
{
o.ConnectionString = Configuration.GetConnectionString("EventHubsConnection");
});
}
The PostConfigure can be used to override the configuration. More about it is available here.
Basically, we are overriding ConnectionString value after all configuring of TOptions is finished.
Related
This is my Object Class
public class MyObject
{
Public string Var1 { get; set; }
Public string Var2 { get; set; }
}
This is a get function of my controller class
[HttpGet]
public IActionResult GetObjList()
{
return Ok(new GenericModel<List<MyObject>>
{
Data = myobjectList
});
}
The GenericModel contains
public class GenericModel<T>
{
public T Data { get; set; }
public string[] Errors { get; set; }
}
My expected result look like this
{
"Data": [
{
"Var1": "val1",
"Var2": "val2"
}
]
}
But I'm getting this,
{
"data": [
{
"var1": "val1",
"var2": "val2"
}
]
}
I just want to get the output key values as same as the object variables, (in PascalCase)
I tried the solutions to add "AddJsonOptions" into the Startup.cs but they did not work. And I want the response as Pascal case, only for this controller requests, not in all requests including other controllers. (Sounds odd, but I want to try it) Are there any solutions? Is is impossible?
There may be another solution but I suggest building ContentResult yourself with JsonSerializer:
[HttpGet]
public IActionResult GetObjList()
{
return this.Content(JsonSerializer.Serialize(yourResult, yourJsonOption), "application/json");
}
For Pascal Case serialization use this code in Startup.cs:
services.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy= null;
);
I'm using Mongodb database with ASP.NET core for creating this API project and I ended up getting this error sorry it's an exception.Here I'm just using get method to retrieve all values from database. I have surfed the internet for the solution and it seems like no one got this kind of exception.
This is the interface for activity model:
using Domain.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Domain.Repositories.Contracts
{
public interface IActivityRepository
{
List<Activity> Get();
Activity Get(string id);
Activity Create(Activity activity);
void Update(string id);
void Remove(string id);
void Update(string id, Activity activity);
}
}
and it's implementation:
using Domain.Contexts;
using Domain.Models;
using Domain.Repositories.Contracts;
using MongoDB.Driver;
namespace Domain.Repositories.Mongo
{
public class ActivityRepository : IActivityRepository
{
private readonly IMongoCollection<Activity> _activity;
public ActivityRepository(IOneboardDtatabaseSettings settings, IMongoClient mongoclient)
{
var database = mongoclient.GetDatabase(settings.DatabaseName);
_activity = database.GetCollection<Activity>(settings.ActivitesCollectionName);
}
Activity IActivityRepository.Create(Activity activity)
{
throw new NotImplementedException();
}
public List<Activity> Get()
{
return _activity.Find(activity => true).ToList();
}
Activity IActivityRepository.Get(string id)
{
throw new NotImplementedException();
}
void IActivityRepository.Remove(string id)
{
throw new NotImplementedException();
}
void IActivityRepository.Update(string id)
{
throw new NotImplementedException();
}
void IActivityRepository.Update(string id, Activity activity)
{
throw new NotImplementedException();
}
}
}
The exeception part lies here:
var database = mongoclient.GetDatabase(settings.DatabaseName);
program.cs :
using API.Config;
using Domain.Contexts;
using Domain.Repositories.Contracts;
using Domain.Repositories.Mongo;
using Microsoft.Extensions.Options;
using MongoDB.Driver;
var builder = WebApplication.CreateBuilder(args);
/*****************************************
* SERVICES
* **************************************/
// Add services to the container.
builder.Services.Configure<OneboardDatabaseSettings>(
builder.Configuration.GetSection(nameof(OneboardDatabaseSettings)));
builder.Services.AddSingleton<IOneboardDtatabaseSettings>(sp =>
sp.GetRequiredService<IOptions<OneboardDatabaseSettings>>().Value);
builder.Services.AddSingleton<IMongoClient>(s =>
new MongoClient(builder.Configuration.GetValue<string>("OneboardDatabase:ConnectionString")));
builder.Services.AddScoped<IActivityRepository, ActivityRepository>();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
/*****************************************
* PIPELINE
* **************************************/
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
// Global error handling registration
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/error");
}
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
And this is appsettings.json file and as per exception database and connection string looks fine to me
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "D:/Solustem/OneBoard/Logs/oneboard-provider-api-.log",
"rollingInterval": "Day",
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {CorrelationId} {Level:u3}] {Username} {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "Console"
}
]
},
"CORS": {
"AllowedOrigins": [
"http://localhost:19006"
]
},
"JWT": {
"ValidAudience": "User",
"ValidIssuer": "http://localhost:5144",
"Key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyYjZiOTVhOTMwMjFjMDJhODc5NDRhYSIsImlhdCI6MTY1NjE0NDYxNCwiZXhwIjozMzIxMzc0NDYxNH0.SC7JIawGhcleTEo7LpYptHqJ_xYmEQIuPWR8XF20FGQ",
// This is to identify the hostel the user can manage
"HostelID": "HostelID"
},
"Services": {
"Strapi": {
"BaseURL": "http://localhost:1337"
},
"Kaleyra": {
"BaseURL": "https://api.kaleyra.io/v1/HXIN1705702387IN",
"Key": "A673e59a98e51f4e6f766d67f603000b6"
}
},
"OneboardDatabase": {
"ActivitesCollectionName": "activities",
"ConnectionString": "mongodb+srv://Muralidharan:murali123#cluster0.fwttvjg.mongodb.net/?retryWrites=true&w=majority",
"DatabaseName": "myFirstDatabase"
}
}
This is IOneboardDatabaseSettings
namespace Domain.Contexts
{
public interface IOneboardDtatabaseSettings
{
string ActivitesCollectionName { get; set; }
string ConnectionString { get; set; }
string DatabaseName { get; set; }
}
}
and it's implementation OneboardDatabaseSettings
namespace Domain.Contexts
{
// This class acts as a template for configurations in appsettings file
public class OneboardDatabaseSettings: IOneboardDtatabaseSettings
{
public string ActivitesCollectionName { get; set; } = String.Empty;
public string ConnectionString { get; set; } = String.Empty;
public string DatabaseName { get; set; } = String.Empty;
}
}
I have tried my best to find out why this exception throwing and I have no idea.
// Add services to the container.
builder.Services.Configure<OneboardDatabaseSettings>(
builder.Configuration.GetSection('OneboardDatabase')
);
I get some idea about the policy based authorization in .NET 6.0 based on Microsoft article.
https://learn.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-6.0
The article mentioned about to hard code the policy in the authorization attribute. I have REST API' and I want to assign permissions to them in some configuration for example in file and how can I can define the policy in the configuration what ingredients it should include so that I can load the policy from the file and then apply on startup to the authorization attribute. How to apply it to authorization attribute I see the following link Bind AuthorizationPolicy to Controller/Action without using AuthorizeAttribute
I am here only interested how I can define the polices in the configuration file(appsettings.json) what template or fields it should have. I know It will move it to database later but I need it for the proof of concepts. I am not sure do we really need to define the policy or we can define the permissions per API and then create policy automatically based on the API permission? Any help in this context will be appreciated.
Regards,
IK
I tried as below :
var policylist = new List<AuthOption>();
Configuration.GetSection("PolicyList").Bind(policylist);
services.AddAuthorization(options => {
policylist.ForEach(x =>
{
options.AddPolicy(x.PolicyName, policy =>
{
x.Requirement.ForEach(y =>
{
Type type = Type.GetType(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Namespace+"."+y.RequirementName);
if (y.Inputs!=null)
{
var requirement = (IAuthorizationRequirement)Activator.CreateInstance(type,y.Inputs);
policy.AddRequirements(requirement);
}
else
{
var requirement = (IAuthorizationRequirement)Activator.CreateInstance(type);
policy.AddRequirements(requirement);
}
});
});
});
});
added some class:
public class AuthOption
{
public AuthOption()
{
Requirement = new List<Requirement>();
}
public string PolicyName { get; set; }
public List<Requirement> Requirement { get; set; }
}
public class Requirement
{
public string RequirementName { get; set; }
public string Inputs { get; set; }
}
public class MinimumAgeRequirement : IAuthorizationRequirement
{
public MinimumAgeRequirement(string minimumAge) =>
MinimumAge = minimumAge;
public string MinimumAge { get; }
}
public class AnotherRequirement : IAuthorizationRequirement
{
}
in appsettings.json:
"PolicyList": [
{
"PolicyName": "policy1",
"Requirement": [
{
"RequirementName": "MinimumAgeRequirement",
"Inputs": "21"
},
{
"RequirementName": "AnotherRequirement"
}
]
},
{
"PolicyName": "policy2",
"Requirement": [
{
"RequirementName": "AnotherRequirement"
}
]
}
]
Result:
I'm using .Net and i need to use inside a virtual field of a model a variable defined inside appsettings.json. Something like:
public class MyClass : BaseClass {
[NotMapped]
public virtual string? identifier { get{
return $"{PlantAcronym} {otherstuff}";
}
}
}
appsetting.json looks like this:
{
"Logging": {
...
},
"AllowedHosts": "*",
"Settings":{
"PlantAcronym": "Z",
...,
"SQLConnectionString": "...",
...
}
}
basically, i need to get the variable without using a constructor.
I've tried approaches using static classes like the most answered question here but they return null and i don't know why.
My setup look like this:
service.Configure<Settings>(options =>
{
options.z = _configuration.GetSection("Settings").GetSection("PlantAcronym").Value;
});
public class Settings{
public string z { get; set; }
public static string PlantAcronym { get; set;}
public Settings(string configuration){
z = configuration;
PlantAcronym = z;
}
public static string getPlantAcronym(){
return PlantAcronym;
}
}
I know this issue has been responded to before, but I cannot seem to get it to work in my case. The solution in Visual Studio contains several project, including WepApi-project (asp.net core), and a class library project. In the class library project I need to access some info in the appsettings.json, residing in the WebApi-project. I've tried to followed different tutorials, which has lead to the following so far:
Appsettings.json
{
"LoginSettings": {
"email": "test#test.com",
"password": "12345678"
}
}
Class modeling configuration (resides in class library project):
LoginSettings
public class LoginSettings
{
public string Email { get; set; }
public string Password { get; set; }
}
Startup.cs (WebApi-project):
public void ConfigureServices(IServiceCollection services)
{
var loginSettings = new LoginSettings
{
Email = Configuration["LoginSettings:email"],
Password = Configuration["LoginSettings:password"]
};
services.AddSingleton(loginSettings);
services.AddOptions();
}
Class in which I need the settings
public static class Test
{
private readonly LoginSettings settings;
public static async Task<string> GetTokenAsync()
{
var email = settings.Email;
...
}
}
I cannot get anything from LoginSettings. In addition, I have tried to make Test-class non-static in order to inject LoginSettings into the constructor. But when I then try to instantiate Test-class, it asks for an instance of LoginSettings. I don't really feel for making Test-class non-static, as it's only purpose is to return a string to another class, and it needs the LoginSettings to do so. What do I do wrong?
Regards.
EDIT
I have made the class Test non-static. What do I pass in when instatiating it?
In the Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<LoginSettings>(Configuration.GetSection("LoginSettings"));
}
In the controller:
public class HomeController : Controller
{
private string _email { get; set; }
private string _password { get; set; }
public HomeController(IOptions<LoginSettings> options)
{
var login = options.Value;
_email = login.Email;
_password = login.Password;
}
public IActionResult GetTokenAsync()
{
// _email: "test#test.com"
// _password: "12345678"
}
}
NOTE: I suggest you name the property name in the appsettings.json like this:
{
"LoginSettings": {
"Email": "test#test.com",
"Password": "12345678"
}
}
Use Email and Password instead of email and password.
UPDATE (for I'm not going to use the LoginSettings in a controller. I'm going to use it in a class in the class library project):
public class MyLib
{
private string _email { get; set; }
private string _password { get; set; }
public MyLib(IOptions<LoginSettings> options)
{
var login = options.Value;
_email = login.Email;
_password = login.Password;
}
public async Task<string> GetTokenAsync()
{
// _email: "test#test.com"
// _password: "12345678"
}
}
UPDATE 2
To use this library. You cannot use it like this:
var lib = new MyLib(???)
Since MyLib (or Test in your example) is a service, you pass it in another constructor before using:
public class AnotherClass
{
private MyLib _lib { get; set; }
public AnotherClass(MyLib lib)
{
_lib = lib;
}
public async Task UseIt()
{
var token = await _lib.GetTokenAsync();
}
}
Ok, I'm trying to explain how it works in my case.
In my ClassLibrary I have the following extension method
public static class MyClassLibraryExtensions
{
public static IServiceCollection AddMyClassLibrary(this IServiceCollection services, LoginSettings options)
{
services.AddSingleton<LoginSettings>(options);
return services;
}
}
then in Web.API project
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
var loginSettings = new LoginSettings
{
Email = Configuration["LoginSettings:email"],
Password = Configuration["LoginSettings:password"]
};
services.AddMyClassLibrary(loginSettings);
...
}
and use it
public class Test
{
private readonly LoginSettings _settings;
public Test(LoginSettings loginSettings)
{
_settings = loginSettings;
}
public static async Task<string> GetTokenAsync()
{
var email = _settings.Email;
...
}
}