Load section of config file into dictionary in net 5.0 - .net-5

I have to work on an application in net 5.0 not developed by me, that I don't know.
I would like to add a section in the config file and load it into a dictionary.
this is the section in config file:
{
"MyApp": {
"ServiceExceptions": [
{ "Key1": "Value1" },
{ "Key2": "Value2" }
]
}
}
this code load the configuration:
public static IConfiguration GetConfiguration(string name)
{
IConfiguration oConfiguration = null;
string basePath = Path.GetDirectoryName(typeof(SharedHelper).Assembly.Location);
string configPath = Path.Combine(basePath, "Config");
string fileConfig = string.Format("{0}.{1}.json", name, Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
oConfiguration = new ConfigurationBuilder()
.SetBasePath(configPath)
.AddJsonFile(fileConfig, optional: false, reloadOnChange: true)
.Build();
return oConfiguration;
}
this is the code to load to bind the dictionary, but myExceptions is null:
_Configuration = GetConfiguration("BD.Authentication.DWA");
Dictionary<string, string> myExceptions = null;
_Configuration.GetSection("MyApp:ServiceExceptions").Bind(myExceptions);
Debug.WriteLine(myExceptions.Count); // throws exception null reference
somewhere are loaded the data, but i dont know how to pull out

Just move the config file in:
{
"MyApp": {
"ServiceExceptions":
{ "Key1": "Value1" },
{ "Key2": "Value2" }
}
}
and retrive the values:
var serviceTypeExceptions = _Configuration.GetSection("MyApp:ServiceExceptions").Get<Dictionary<string, string>>();

Related

Schema validation failed by Swagger/OpenAPI online validator

I have a config my Swagger schema, /api-docs -> openapi 3.0.1:
#Configuration
public class SwaggerConfig {
#Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.components(new Components().addSecuritySchemes("Bearer",
new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("Bearer")
.in(SecurityScheme.In.HEADER).name("Authorization")))
.info(new Info().title("SSM API").version("0.1"));
}
}
Example of controller:
#Tag(name = "MetalBalance", description = "Контроллер баланса металла")
#RestController
#RequestMapping(path = "/metal-balance", produces = MediaType.APPLICATION_JSON_VALUE)
#SecurityRequirement(name = "Bearer")
#ResponseBody
#RequiredArgsConstructor
public class MetalBalanceController {
...
#DeleteMapping("/operations/{id}")
#Operation(summary = "Удаление операции над агрегатом")
#Parameters(value = {
#Parameter(in = ParameterIn.PATH, name = "id", example = "720050516121420278143",
description = "Идентификатор операции",
content = #Content(schema = #Schema(type = "integer"))),
})
#RolesAllowed({"MASTER_SHIHTA", "NACH_SMEN_VZKKC1", "MASTER_KONV", "FERRO_R6", "NACH_SMEN_VZKKC1", "FERRO_R", "DESIGNER",
"KONV_R", "LAB_ST_PR", "NACH_SMEN_VZKKC1", "NACH_UPPVS", "ING_CEN_CEH", "RAB_UPK", "UPK_R",
"MASTER_VAK", "VAK_R", "R_VAKUUMAT", "MASTER_UDM", "UDM_R"})
public void deleteOperation(#PathVariable("id") BigInteger operationId) {
balanceService.deleteUnitOperation(operationId);
}
}
openapi response, what i have from '/api-docs' endpoint:
"/metal-balance/operations/{id}": {
"delete": {
"tags": [
"MetalBalance"
],
"summary": "Удаление операции над агрегатом",
"operationId": "deleteOperation",
"parameters": [
{
"name": "id",
"in": "path",
"description": "Идентификатор операции",
"required": true,
"example": 720050516121420300000,
"content": {
"*/*": {
"schema": {
"type": "integer"
}}}}],
"responses": {
"200": {
"description": "OK"
},
"400": {
"description": "Bad Request",
"content": {
"*/*": {
"schema": {
"type": "object"
}}}}},
"security": [
{
"Bearer": []}
]}}
When I try to validate it by Swagger/OpenAPI online validator I recieved the exceptions, attached: Validation Error
How to tune my config correct?
Thanks in advance!
There's no need to wrap the schema into content in case of path parameters and primitive parameters in general (i.e. numbers/strings/booleans). The #Content annotation is typically only used with request bodies and responses.
Replace
#Parameter(in = ParameterIn.PATH, name = "id", example = "720050516121420278143",
description = "Идентификатор операции",
content = #Content(schema = #Schema(type = "integer"))),
with
#Parameter(in = ParameterIn.PATH, name = "id", example = "720050516121420278143",
description = "Идентификатор операции",
schema = #Schema(type = "integer")), // <----------

How to log Serilog debug messages conditionally in .NET 6?

I am working on a .net 6 application. I have used Serilog for logging. I have received a request to log the debug logs based on the database settings.
Below is my setting table:
Create table ApplicationSettings
(
Id UNIQUEIDENTIFIER PRIMARY KEY NOT NULL,
Name VARCHAR(500) NOT NULL,
[Value] VARCHAR(200) NOT NULL,
CreatedOn DATETIMEOFFSET,
Active BIT
)
INSERT INTO ApplicationSettings VALUES(NEWID(),'Log Debug Message','true', GETDATE(),1)
SELECT * FROM ApplicationSettings
If "Log Debug Message is true" in above table then only I have to log the debug messages of Serilog or else I don't have to log the debug message.
Here is my appsettings.json
{
"ConnectionStrings": {
"DefaultConnection": "Server=Something;Database=SampleDb;Trusted_Connection=True;MultipleActiveResultSets=true;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Serilog": {
"Using": [ "Serilog.Enrichers.ClientInfo", "Serilog.Sinks.MSSqlServer" ],
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning",
"System": "Warning",
"System.Net.Http.HttpClient": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithClientIp", "WithClientAgent" ],
"WriteTo": [
{
"Name": "MSSqlServer",
"Args": {
"connectionString": "Server=Something;Database=SampleDb;Trusted_Connection=True;MultipleActiveResultSets=true;",
"sinkOptionsSection": {
"tableName": "tblLogs",
"autoCreateSqlTable": true
},
"restrictedToMinimumLevel": "Debug",
"columnOptionsSection": {
"primaryKeyColumnName": "Id",
"addStandardColumns": [ "LogEvent", "SourceContext" ],
"removeStandardColumns": [ "Properties" ],
"additionalColumns": [
{
"ColumnName": "ClientIP",
"PropertyName": "ClientIp",
"DataType": "nvarchar"
}
]
}
}
}
]
}
}
Program.cs
using Serilog;
using Serilog.Events;
var builder = WebApplication.CreateBuilder(args);
#region Configure serilog
builder.Logging.ClearProviders();
IConfigurationRoot configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
.Build();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.MinimumLevel.Override("Microsoft", LogEventLevel.Error)
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Error)
.MinimumLevel.Override("Serilog", LogEventLevel.Error)
.Enrich.FromLogContext()
.Enrich.WithClientIp()
.Enrich.WithClientAgent()
.CreateLogger();
Log.Logger = logger;
builder.Logging.AddSerilog(logger);
builder.Host.UseSerilog();
#endregion
// Add services to the container.
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Configure the HTTP request pipeline.
if(app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else if(app.Environment.IsStaging() || app.Environment.IsProduction())
{
app.UseExceptionHandler("/Error");
}
app.UseSerilogRequestLogging();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
HomeController.cs
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
//Here If "Log Debug Message is set to true" in "ApplicationSettings" table
//then only log debug message of Serilog or else don't log.
Log.Debug("Started executing Privacy");
try
{
int a = 1;
int b = 0;
int c = a / b;
}
catch (Exception ex)
{
Log.Error(ex, ex.Message);
}
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
Can anybody help me on this? thanks.

HTML Helper Class

I am using this code and is working fine.
#Html.TextBox("myname", "somevalue", new { #class = "css-class", #onclick = "alert('demo');" id="mynewID"})
But there is another overload for this:
HTMLHelper.Textbox(string name, object value, IDictionary<string,object> htmlattribute)
I am using like:
#Html.TextBox("myname", "", new Dictionary<string, object> { { "id", "f","class","ds" } })
but getting compilation error...please help
The error you are getting is due to the incorrect syntax used in the dictionary initializer. You can see that easily if you add this code to a class and try to compile:
var dict = new Dictionary<string, object> { { "id", "f", "class", "ds" } };
You will see that you get the error:
No overload for method 'Add' takes 4 arguments
You need to pass each object to the dictionary as a key value pair, as in this code (notice each key-value pair surrounded by curly brackets):
var dict = new Dictionary<string, object> { { "id", "f" }, { "class", "ds" } };
So you can use that overload of the HtmlHelper as in the following example:
#Html.TextBox("myname", "", new Dictionary<string, object> { { "id", "f"}, {"class", "ds" } })

Not able to get TermVector results properly in SolrNet

I'm not able to get TermVector results properly thru SolrNet. I tried with the following code.
QueryOptions options = new QueryOptions()
{
OrderBy = new[] { new SortOrder("markupId", Order.ASC) },
TermVector = new TermVectorParameters
{
Fields = new[] { "text" },
Options = TermVectorParameterOptions.All
}
};
var results = SolrMarkupCore.Query(query, options);
foreach (var docVectorResult in results.TermVectorResults)
{
foreach (var vectorResult in docVectorResult.TermVector)
System.Diagnostics.Debug.Print(vectorResult.ToString());
}
In the above code, results.TermVectorResults in the outer foreach gives the proper count whereas docVectorResult.TermVector in the inner foreach is empty.
I've copied the generated solr query of the above code and issued against solr admin and I'm properly getting the termVectors values. The actual query I issued is below
http://localhost:8983/solr/select/?sort=markupId+asc&tv.tf=true&start=0&q=markupId:%2823%29&tv.offsets=true&tv=true&tv.positions=true&tv.fl=text&version=2.2&rows=50
First you should check HTTP query to sure termvector feature is set property.
If it's not OK, change your indexing based on:
The Term Vector Component
If it is OK,You can use "ExtraParams" by changing the handler to termvector handler. Try this:
public SolrQueryExecuter<Product> instance { get; private set; }
public ICollection<TermVectorDocumentResult> resultDoc(string q)
{
string SERVER="http://localhost:7080/solr/core";//change this
var container = ServiceLocator.Current as SolrNet.Utils.Container;
instance = new SolrQueryExecuter<Product>(
container.GetInstance<ISolrAbstractResponseParser<Product>>(),
new SolrConnection(SERVER),
container.GetInstance<ISolrQuerySerializer>(),
container.GetInstance<ISolrFacetQuerySerializer>(),
container.GetInstance<ISolrMoreLikeThisHandlerQueryResultsParser<Product>>());
instance.DefaultHandler = "/tvrh";
SolrQueryResults<Product> results =
instance.Execute(new SolrQuery(q),
new QueryOptions
{
Fields = new[] { "*" },
Start = 0,
Rows = 10,
ExtraParams = new Dictionary<string, string> {
{ "tv.tf", "false" },
{ "tv.df", "false" },
{ "tv.positions", "true" },
{ "tv", "true" },
{ "tv.offsets", "false" },
{ "tv.payloads", "true" },
{ "tv.fl", "message" },// change the field name here
}
}
);
return results.TermVectorResults;
}

Can I display contents of Application or Cache objects using Glimpse in an MVC project?

The ASP.NET WebForms trace output has a section for Application State. Is it possible to see the same using Glimpse?
In my home controller's Index() method, I tried adding some test values, but I don't see the output in any of the Glimpse tabs.
ControllerContext.HttpContext.Application.Add("TEST1", "VALUE1");
ControllerContext.HttpContext.Cache.Insert("TEST2", "VALUE2");
I didn't see anything in the documentation either.
I don't think that there is an out-of-the-box support for this, but it would be trivial to write a plugin that will show this information.
For example to show everything that's stored in the ApplicationState you could write the following plugin:
[Glimpse.Core.Extensibility.GlimpsePluginAttribute]
public class ApplicationStateGlimpsePlugin : IGlimpsePlugin
{
public object GetData(HttpContextBase context)
{
var data = new List<object[]> { new[] { "Key", "Value" } };
foreach (string key in context.Application.Keys)
{
data.Add(new object[] { key, context.Application[key] });
}
return data;
}
public void SetupInit()
{
}
public string Name
{
get { return "ApplicationState"; }
}
}
and then you get the desired result:
and to list everything that's stored into the cache:
[Glimpse.Core.Extensibility.GlimpsePluginAttribute]
public class ApplicationCacheGlimpsePlugin : IGlimpsePlugin
{
public object GetData(HttpContextBase context)
{
var data = new List<object[]> { new[] { "Key", "Value" } };
foreach (DictionaryEntry item in context.Cache)
{
data.Add(new object[] { item.Key, item.Value });
}
return data;
}
public void SetupInit()
{
}
public string Name
{
get { return "ApplicationCache"; }
}
}

Resources