Why IConfiguration object always return null in .net core? - asp.net-core

I have this Dblayer class.
I am trying to read the connection string from the app.setting.
Here is my class
public class DbLayer
{
[Inject]
private static IConfiguration Configuration { get; set; }
public DbLayer()
{
}
public DbLayer(IConfiguration _configuration)
{
Configuration = _configuration;
}
public const string CONNECTION_STRING_NAME = "CustomersDatabase";
private static string _connectionString = string.Empty;
public static string ConnectionString
{
get
{
if (_connectionString == string.Empty)
{
_connectionString = "Data Source=.;Initial Catalog=CustomersRegistrations;" +
"Integrated Security=SSPI; " +
"Encrypt=False;";
_connectionString = Configuration.GetConnectionString(CONNECTION_STRING_NAME);
}
return _connectionString;
}
}
}
In my startup class, I have the following:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
The problem is Configuration object is always null...
Any reason for that?

Related

AutoMapperMappingException: Missing type map configuration or unsupported mapping IN .NET 6

I have this entity:
public class Genres
{
public int Id { get; set; }
[Required(ErrorMessage ="the field {0} is required")]
[StringLength(50)]
[FirstLetterUpperCase]
public string Name { get; set; }
}
And this DTO or model:
public class GenresDTO
{
public int Id { get; set; }
public string Name { get; set; }
}
I have initiated my mapper like this:
public class AutoMapperClass : Profile
{
public AutoMapperClass()
{
generateMapper();
}
private void generateMapper()
{
CreateMap<GenresDTO, Genres>().ReverseMap();
CreateMap<GenresCreationDTO, Genres>();
}
}
I have also written this part of code in my program.cs :
builder.Services.AddAutoMapper(typeof(IStartup));
I am using .NET 6 and Visual Studio, and when I run my project, I get an error that is mentioned in the title and its related to this section :
public async Task<ActionResult<List<GenresDTO>>> Get()
{
var genres = await dbContext.Genres.ToListAsync();
return mapper.Map<List<GenresDTO>>(genres);
}
which is in my Controller file, and I initiated the mapper like this :
private readonly ILogger<GenresController> ilogger;
private readonly ApplicationDBContext dbContext;
private readonly IMapper mapper;
public GenresController(ILogger<GenresController> ilogger,
ApplicationDBContext dbContext , IMapper mapper)
{
this.ilogger = ilogger;
this.dbContext = dbContext;
this.mapper = mapper;
}
Should be probably typeof(Program) in registration (assuming that you are using .Net6 where we have only Program.cs)
builder.Services.AddAutoMapper(typeof(Program))
If you have multiple projects in solution,then value used there should be a file in the assembly in which the mapping configuration resides.

Get session value in parameterless constructor in ASP .NET Core

I have a class with a parameterless constructor and I am wondering how to get a value from the session. I have tried dependency injection but since I am using this class for deserialization, the httpcontextaccessor is always null.
public class Category
{
public Category()
{
_language = "french"; <-- how to get value from session
}
private string _Name;
public string Name {
get {
if (!string.IsNullOrEmpty(_language))
{
var dict = new Dictionary<string, string>();
this.localization.FirstOrDefault(x => x.TryGetValue(_language, out dict));
return dict != null && dict.ContainsKey("name") ? dict["name"] : _Name;
}
else
return _Name;
}
set
{
_Name = value;
}
}
public List<Dictionary<string, Dictionary<string, string>>> localization { get; set; }
}
You can get session value in custom model like below:
public class Category
{
private readonly ISession _session; //add this..
public Category(ISession session)
{
_session = session;
_language = _session.GetString("language");
}
private string? _language;
private string _Name;
public string Name {
get {
if (!string.IsNullOrEmpty(_language))
{
var dict = new Dictionary<string, string>();
this.localization.FirstOrDefault(x => x.TryGetValue(_language, out dict));
return dict != null && dict.ContainsKey("name") ? dict["name"] : _Name;
}
else
return _Name;
}
set
{
_Name = value;
}
}
public List<Dictionary<string, Dictionary<string, string>>> localization { get; set; }
}
Test it in Controller:
public IActionResult Index()
{
HttpContext.Session.SetString("language", "en-US");
var model = new CategoryModel(HttpContext.Session);
return View();
}
Be sure add AddSession and UseSession middleware in Program.cs or in Startup.cs.
Reference: Configure session state
but since I am using this class for deserialization, the httpcontextaccessor is always null.
A simple demo you could follow:
Model:
public class CategoryModel
{
private readonly IHttpContextAccessor _contextAccessor;
public CategoryModel(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
_language = contextAccessor.HttpContext.Session.GetString("language");
}
//........
}
Test in Controller:
public class HomeController : Controller
{
private readonly IHttpContextAccessor _contextAccessor;
public HomeController(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public IActionResult Index()
{
HttpContext.Session.SetString("language", "en-US");
var model = new CategoryModel(_contextAccessor);
return View();
}
}
Register the service like:
//.....
builder.Services.AddSession();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSession();
app.UseRouting();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
So I created a static class:
public static class AppContext
{
public static IHttpContextAccessor HttpContextAccessor { get; set; }
public static void Configure(IHttpContextAccessor accessor)
{
HttpContextAccessor = accessor;
}
}
And then in the class where I couldn't do dependency injection, I was able to get the session:
public Category()
{
_language = AppContext.HttpContextAccessor.HttpContext.Session.GetString("language");
}
Had to add this to Configure in Startup:
AppContext.Configure(context);

How to download file from wwwroot folder in dot core api using Mediatr pattern?

I am trying to download wwwroot file where file is saved i want to download file by filename only which i am sending from my angular code.
in controller my code is like this
[HttpPost("DownloadMPWorthyFile")]
public async Task<ActionResult<bool>> DownloadMPWorthyFile(DownloadMPWorthyFileCommand command)
{
return await Mediator.Send(command);
}
in DownloadMPWorthyFileCommand command i have added
using AutoMapper;
using Kaizen.Common.Interfaces;
using Kaizen.Common.Logger;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Kaizen.Domain.Entities;
using Kaizen.Application.Common.Services.EmailService;
using EmailActions = Kaizen.Domain.Enums.EmailActions.Actions;
using Kaizen.Common.Models;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Hosting;
namespace Kaizen.Application.Kaizen.Command
{
public class DownloadMPWorthyFileCommand : IRequest<bool>
{
public string FileName { get; set; }
public string PageName { get; set; }
public string IdeaNumber { get; set; }
}
public class GetKaizenDownloadfileResponse
{
public int StatusCode { get; set; }
public string Message { get; set; }
public string ErrorMessage { get; set; }
public List<getdata> Data { get; set; }
}
public class getdata
{
public string FileName { get; set; }
public string Method { get; set; }
public string PageName { get; set; }
}
public class DownloadMPWorthyFileCommandHandle : IRequestHandler<DownloadMPWorthyFileCommand, bool>
{
private readonly IKaizenDBContext _context;
private readonly IMapper _mapper;
private readonly ILogger<kaizenUploadFile> _logger;
private readonly IEmailService _emailService;
private IHostingEnvironment Environment;
public DownloadMPWorthyFileCommandHandle(IKaizenDBContext context, IMapper mapper, ILogger<SendMailForMPWorthyCommandHandler> logger, IEmailService emailService, IOptions<AppSettings> appSettings, IHostingEnvironment _environment)
{
_context = context;
_mapper = mapper;
//_logger = logger;
_emailService = emailService;
Environment = _environment;
// _appSettings = appSettings.Value;
}
public async Task<bool> Handle(DownloadMPWorthyFileCommand request, CancellationToken cancellationToken)
{
bool retval = false;
var MPWorthyFile = _context.DocumentUploaded.Where(e => e.IdeaNumber == request.IdeaNumber && e.PageName==request.PageName);
if (MPWorthyFile != null)
{
string wwwPath1 = this.Environment.WebRootPath;
string imgnm1 = "/document/" + request.FileName;
string filePath1 = wwwPath1 + imgnm1;
string imageName1 = filePath1;
var net1 = new System.Net.WebClient();
var path1 = wwwPath1 + filePath1;
var data1 = net1.DownloadData(filePath1);
var content1 = new System.IO.MemoryStream(data1);
retval= true;
}
else
{
retval = false;
}
return retval;
}
}
}
i have done code in this way but its not working in return type i keep getting error,is anyone know correct way to download the file from wwwroot?
You should check the IHostingEvironment, there is an WebRootFileProvider with which you check for file and open stream on those.
var file = _environment.WebRootFileProvider.GetFileInfo("...");
if (file.Exists)
{
var stream = file.CreateReadStream();
// Go on from here...
}

I cannot retrieve connection string in DbContext class in .NET Core 2.2 Razor Pages

In Startup.cs Configure Services this works:
var connection = Configuration["ConnectionStrings:DefaultConnection"];
services.AddDbContext<MyDbContext>(
options => { options.UseSqlServer(connection); });
In my MyDbContext.cs class this doesn't work:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using OESAC.Models;
namespace OESAC.Models
{
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options)
{ }
public DbSet<Courses> Courses { get; set; }
public DbSet<Sponsors> Sponsors{ get; set; }
public IConfiguration Configuration { get; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connection = Configuration["ConnectionStrings:DefaultConnection"];
optionsBuilder.UseSqlServer(connection);
;
}
}
}
I can hardcode the connection string but I want it to dynamically change based on my appSettings.Development.json and appSettngs.json (production). I can't believe the time I've spent trying to figure this out. It has cost me way over what I am being paid.
You need to inject IConfiguration in constructor to have an access to configuration.
public class MyDbContext : DbContext
{
private readonly IConfiguration _configuration;
public MyDbContext(IConfiguration configuration)
{
_configuration = configuration
}
public DbSet<Courses> Courses { get; set; }
public DbSet<Sponsors> Sponsors{ get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connection = _configuration["ConnectionStrings:DefaultConnection"];
optionsBuilder.UseSqlServer(connection);
}
}
Startup.cs:
services.AddDbContext<ApplicationDbContext>();

asp.net core 2 Access httpcontext from scoped DI service accessed through hangfire task

I have an asp.net core2 application with hangfire. Configuration works fine for basic tasks, however now I need to enqueue a background job which accesses the dependency injected httpcontext and dbcontext and I am getting null reference exceptions for httpcontext - I understand why this would be, but...
Can I configure hangfire's enqueue such that the httpcontext and dbcontext from which the task is fired are included with the job? The job is always originally fired from within a controller where the contexts are available. The job is a method on ApprovalService which has _userservice injected into its constructor. _Userservice has the httpContext injected in its constructor.
As I understand it, the graph should be able to resolve this, it is just a question of how...
I dont want to refactor to pass these as arguments as the services are used elsewhere where they do have access to the contexts.
The
My startup is as follows (a lot of things removed for clarity)
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
private IHostingEnvironment _env;
public static string connection;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc(config => {
config.Filters.Add(new AuthorizeFilter(authorizePolicy));
config.OutputFormatters.OfType<StringOutputFormatter>().Single().SupportedMediaTypes.Add("text/html");
})
.AddJsonOptions(options =>
{
options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
connection = Configuration.GetConnectionString("(default)");
services.AddDbContext<CpContext>(options =>
{
options.UseSqlServer(connection);
});
services.AddHangfire(configuration => configuration
.UseSqlServerStorage(connection));
services.AddScoped<IApprovalService, ApprovalService>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<SystemControlService>();
services.AddScoped<ProjectControlService>();
services.AddIdentity<CpIdentityUser, IdentityRole>().AddUserManager<cpUserManager>();
services.AddScoped<ApprovalService>();
services.AddTransient<IEmailService, EmailService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
Log.Information("In configure");
_env = env;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
//app.UseBrowserLink();
}
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
app.UseAuthentication();
app.UseMvc();
app.UseStaticFiles();
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
Authorization = new[] { new CustomAuthorizeFilter() }
});
app.UseHangfireServer();
}
public class CustomAuthorizeFilter : IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
var httpcontext = context.GetHttpContext();
return httpcontext.User.Identity.IsAuthenticated;
}
}
}
I fire the job like this (non job version commented and works - hangfire job hangs on nullreference when trying to get userID from the context);
[Produces("application/json")]
[Route("api/Approvals")]
public class ApprovalsController : Controller
{
private readonly CpContext _context;
private IUserService _userService;
private IBackgroundJobClient _backgroundJobClient;
private ApprovalService _approvalService;
public ApprovalsController(CpContext context, IUserService userService, ApprovalService approvalService, IBackgroundJobClient backgroundJobClient)
{
_context = context;
_userService = userService;
_approvalService = approvalService;
_backgroundJobClient = backgroundJobClient;
}
public class approvalWrapper
{
public int ApprovalId { get; set; }
public List<string> emailTo { get; set; }
public List<string> ccTo { get; set; }
public string ManualApprCode { get; set; }
public int RequestToId { get; set; }
public DateTime RequestDate { get; set; }
public DateTime RequiredDate { get; set; }
public DateTime ResponseDate { get; set; }
public string RequestText { get; set; }
public string ResponseText { get; set; }
public int ApprovalStatusTypeId { get; set; }
public int ApprovalItemTypeId { get; set; }
public int? NcrLinkId { get; set; }
public int? LotItpDetailLinkId { get; set; }
public int? LotQtyLinkId { get; set; }
}
// POST: api/Approvals/sendRequest
[HttpPost("sendRequest")]
public async Task<IActionResult> sendRequest([FromBody] approvalWrapper approvalInfo)
{
if (!ModelState.IsValid) return BadRequest(ModelState);
Approval approval = new Approval()
{
RequestById = _userService.User_ID,
RequestToId = approvalInfo.RequestToId,
RequestDate = approvalInfo.RequestDate,
RequiredDate = approvalInfo.RequiredDate,
RequestText = approvalInfo.RequestText,
NcrLinkId = approvalInfo.NcrLinkId,
LotItpDetailLinkId = approvalInfo.LotItpDetailLinkId,
LotQtyLinkId = approvalInfo.LotQtyLinkId,
ApprovalItemTypeId = approvalInfo.ApprovalItemTypeId,
ApprovalStatusTypeId = 5,
};
try
{
_context.Approval.Add(approval);
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
Log.Error(ex, "Error trying to create approval.");
return StatusCode(422);
}
_backgroundJobClient.Enqueue<IApprovalService>(serv => serv.sendRequestEmailAsync(approval.ApprovalId, approvalInfo.emailTo, approvalInfo.ccTo));
//await _approvalService.sendRequestEmailAsync(approval.ApprovalId, approvalInfo.emailTo, approvalInfo.ccTo);
return Ok(1);
}
}
interface IApprovalService
{
Task<string> getApprovalRequestTextForChecklistItem(int checklistItemId);
Task<string> getApprovalRequestTextForNCR(int NCRId);
Task<bool> sendRequestEmailAsync(int apprToRequestID, List<string> emailTo = null, List<string> ccTo = null);
Task<bool> sendResponseEmailAsync(int apprToRequestID, List<string> emailTo = null, List<string> ccTo = null);
Task<bool> isApprovalCodeValidAsync(string qryString, int apprToRequestID);
}
public class ApprovalService: IApprovalService
{
CpContext _context;
IEmailService _emailService;
private ProjectControlService _projectControlService;
private SystemControlService _systemControlService;
private IUserService _userService;
public ApprovalService(CpContext context, IEmailService emailService, SystemControlService systemControlService,
ProjectControlService projectControlService, IUserService userService)
{
_context = context;
_emailService = emailService;
_userService = userService;
_systemControlService = systemControlService;
_projectControlService = projectControlService;
}
public interface IUserService
{
int Project_ID { get; }
int User_ID { get; }
Task<UserCredDto> AuthenticateAsync(string username, string password);
HashSet<string> getUserPermsForProject(int userID, int ProjectID);
IEnumerable<User> GetAll();
Task<User> GetByIdAsync(int id);
Task<User> GetUserAsync();
Task<User> CreateUserAsync(User user, string password);
Task UpdateAsync(User user, string password = null);
Task<User> DeleteAsync(int id);
bool Exists(int id);
string checkRefreshToken(string refreshToken, UserCredDto tokenOwner, int refreshLifeTime);
Task<string> getNewRefreshTokenAsync(UserCredDto tokenOwner, int refreshLifeTime = 60);
string GetUserName();
Task<UserDto> GetUser();
ClaimsPrincipal GetClaimsPrincipal();
}
public class UserService : IUserService
{
private CpContext _context;
private readonly IHttpContextAccessor _httpcontext;
public UserService(CpContext context, IHttpContextAccessor httpcontext)
{
_context = context;
_httpcontext = httpcontext;
}
}