I cannot retrieve connection string in DbContext class in .NET Core 2.2 Razor Pages - asp.net-core

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>();

Related

How to implement Service inherit from generic repository?

I work on asp.net core mvc blazor application , I have issue I can't implement service inherit from generic repository .
meaning how to inherit from IRepository to get functions below on class server names service :
Insert
Update
GetById
GetList
GetListAsync
Interface generic repository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
public interface IRepository<TEntity> where TEntity : class
{
Task<int> Count(Expression<Func<TEntity, bool>> where);
TEntity GetByID(object id);
TEntity Insert(TEntity entity);
void Update(TEntity entityToUpdate);
Task<ICollection<TType>> Get<TType>(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TType>> select) where TType : class;
Task<bool> Any(Expression<Func<TEntity, bool>> where);
TEntity GetFirst(Expression<Func<TEntity, bool>> where);
TEntity Single(Expression<Func<TEntity, bool>> where);
Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> where);
List<TEntity> GetList(Expression<Func<TEntity, bool>> where);
Task<bool> UpdateBasedOnCondition(Expression<Func<TEntity, bool>> where, Action<TEntity> select);
void Save();
}
class that implement interface as below :
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using UC.AppRepository.Core;
public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
internal AppsRepositoryDBContext _context;
internal DbSet<TEntity> dbSet;
public BaseRepository(AppsRepositoryDBContext context)
{
_context = context;
this.dbSet = _context.Set<TEntity>();
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual TEntity Insert(TEntity entity)
{
var result = dbSet.AddAsync(entity).Result.Entity;
Save();
return result;
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
_context.Entry(entityToUpdate).State = EntityState.Modified;
}
public virtual async Task<bool> UpdateBasedOnCondition(Expression<Func<TEntity, bool>> where, Action<TEntity> select)
{
try
{
var ListOfRecord = await dbSet.Where(where).ToListAsync();
if (null != ListOfRecord && ListOfRecord.Count > 0)
{
ListOfRecord.ForEach(select);
// Save();
await _context.SaveChangesAsync();
return true;
}
return false;
}
catch (Exception ex)
{
return false;
throw;
}
}
public async Task<ICollection<TType>> Get<TType>(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TType>> select) where TType : class
{
if(where == null)
{
return await dbSet.Select(select).ToListAsync();
}
return await dbSet.Where(where).Select(select).ToListAsync();
}
public async Task<int> Count(Expression<Func<TEntity, bool>> where)
{
return await dbSet.Where(where).CountAsync();
}
public async virtual Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> where)
{
// var test = dbSet.Where(where).ToList();
return await dbSet.Where(where).ToListAsync();
}
public virtual List<TEntity> GetList(Expression<Func<TEntity, bool>> where)
{
return dbSet.Where(where).ToList();
}
public async Task<bool> Any(Expression<Func<TEntity, bool>> where)
{
return await dbSet.AnyAsync(where);
}
public TEntity GetFirst(Expression<Func<TEntity, bool>> where)
{
return dbSet.FirstOrDefault(where);
}
public TEntity Single(Expression<Func<TEntity, bool>> where)
{
return dbSet.Single(where);
}
public void Save()
{
try
{
_context.SaveChanges();
}
catch (Exception ex)
{
throw;
}
}
}
so I have class ServerNameService and class interface IserverNamesService
I need to implement insert,update,selectById,selectall functions for server name models
from base repository
public class ServerNameService:IRepository
{
// what i write here
}
public interface IserverNamesService:IRepository
{
// what i write here
}
public class ServerNames
{
[Key]
public int ServerID { get; set; }
public string Server_Name{ get; set; }
public string Server_Type { get; set; }
public string Operating_System { get; set; }
public string Version { get; set; }
public bool IsActive { get; set; }
}
I have issue I can't implement service inherit from generic repository.I have class ServerNameService and class interface IserverNamesService I need to implement insert,update,selectById,selectall functions for server name models from base repository
Well, to directly answer your question, to implement your ServerNameService which derived from IRepository that would would be as following:
IserverNamesService:
public interface IserverNamesService : IRepository<ServerNames>
{
}
Note: Keep it empty because we will use of IRepository and BaseRepository in ServerNamesService class to implement its members.
ServerNamesService:
public class ServerNamesService : BaseRepository<ServerNames>, IserverNamesService
{
public ServerNamesService(ApplicationDbContext context) : base(context)
{
}
public override ServerNames GetByID(object id)
{
return _context.ServerNames.Where(sn => sn.ServerID == (int)id).FirstOrDefault();
}
}
Controller:
[Route("api/[controller]")]
[ApiController]
public class ServerNamesServiceController : ControllerBase
{
private readonly IserverNamesService _serverNamesService;
public ServerNamesServiceController(IserverNamesService namesService)
{
_serverNamesService = namesService;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetById(object id)
{
var item = _serverNamesService.GetByID(id);
if (item == null)
return NotFound();
return Ok(item);
}
}
Program.cs:
builder.Services.AddScoped<IserverNamesService, ServerNamesService>();
Note: Register your ServerNamesService class in your program.cs
UnitOfWork Pattern Implementation:
As long your application would continue evolving and there would be ton of service class, in that scenario, you have to introduce lot of service in your controller. But if you would like to handle those smoothly, you could use UnitOfWork pattern which would contain all of your service together.
Interface:
public interface IUnitOfWork
{
IserverNamesService ServerNamesService { get; }
Task CompleteAsync();
}
Implementation:
public class UnitOfWork : IUnitOfWork, IDisposable
{
private readonly ApplicationDbContext _context;
public IserverNamesService ServerNamesService { get; private set; }
public UnitOfWork(ApplicationDbContext context)
{
_context = context;
ServerNamesService = new ServerNamesService(context);
}
public async Task CompleteAsync()
{
await _context.SaveChangesAsync();
}
public void Dispose()
{
_context.Dispose();
}
}
Controller:
[Route("api/[controller]")]
[ApiController]
public class ServerNamesServiceController : ControllerBase
{
private readonly IUnitOfWork _unitOfWork;
public ServerNamesServiceController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
[HttpGet("{id}")]
public async Task<IActionResult> GetById(object id)
{
var item = _unitOfWork.ServerNamesService.GetByID(id);
if (item == null)
return NotFound();
return Ok(item);
}
}
Output:
Note: If you would like to know more details on repository pattern you could check our official document here and working sample here.
You should pass your Entity as generic type to IRepository in IServerNamesService, and then inheritance ServerNameService from IServerNamesService.
public interface IServerNamesService:IRepository<ServerNames>
{
// your methods interface
}
public class ServerNameService:IServerNamesService{
private readonly IRepository<ServerNames> _repository;
public class ServerNameService(IRepository<ServerNames> repository)
{
_repository = repository;
}
//body of your methods
}

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.

Cascading DropDownList in .NET Core

I am trying to use the tutorial linked below but adapting it to my SQL DB for States, Districts, Schools tables that I already have in place. I am new to .NET Core MVC and do not understand the error nor how to debug it. Any help appreciated.
Cascading DropDownList In .NET Core
Error:
Microsoft.Data.SqlClient.SqlException: 'Invalid object name 'State'.'
This exception was originally thrown at this call stack:
[External Code]
CascadingExample.Controllers.HomeController.Index() in HomeController.cs
[External Code]
using CascadingExample.Entities;
using CascadingExample.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace CascadingExample.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly MyDBContent _con;
public HomeController(ILogger<HomeController> logger, MyDBContent con)
{
_logger = logger;
_con = con;
}
public IActionResult Index()
{
ViewBag.StateList = _con.State.ToList();
return View();
}
public JsonResult GetDistrictByStateID(int statedID)
{
var data = _con.District.Where(x => x.StateID == statedID).ToList();
return Json(data);
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
The error means the table named 'State' has not created or the Database you are referring has not created
I checked the dbcontext in your tutorial,and it will not create the table"State".
public class MyDBContent:DbContext
{
private IConfigurationRoot _config;
public MyDBContent(IConfigurationRoot config, DbContextOptions options) : base(options)
{
_config = config;
}
public DbSet<Category> Category { get; set; }
public DbSet<SubCategory> SubCategory { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer(_config["ConnectionStrings:DefaultConnection"]);//connection string get by appsetting.json
}
}
You need to add these codes:
public DbSet<State> State { get; set; }

How to add more fields to ASP.NET Core Identity?

I am using .NET 5 - version 5.0.100-rc.1.20452.10 .
I customized table AspNetUsers success, by this way
using Microsoft.AspNetCore.Identity;
using System;
namespace shadow.Models
{
public class ApplicationUser : IdentityUser
{
public string Fullname { get; set; }
public string AliasName { get; set; }
public string SecondMobile { get; set; }
public string About { get; set; }
public string Avatar { get; set; }
public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }
}
}
and
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using shadow.Models;
namespace shadow.Data
{
public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public virtual DbSet<ApplicationUser> ApplicationUsers { get; set; }
I am looking for a similar solution with table AspNetRoles. I need add filed Description to table AspNetRoles, how to archive this? Please guide me how to make change in ApplicationDbContext.
My effort: I tried
using Microsoft.AspNetCore.Identity;
namespace shadow.Models
{
public class ApplicationRole : IdentityRole
{
public string Description { get; set; }
}
}
but error
I feel hard when decare ApplciationRole to ApplicationDbContext
As we can see in the sourcecode Microsoft.AspNetCore.Identity.EntityFrameworkCore does not have a class for IdentityDbContext<TUser, TRole>. It has classes IdentityDbContext<TUser> and IdentityDbContext<TUser, TRole, TKey>. Hence, as described in point 5 of documentation
If a custom ApplicationRole class is being used, update the class to inherit from IdentityRole. For example:
using System;
using Microsoft.AspNetCore.Identity;
public class ApplicationRole : IdentityRole<Guid>
{
public string Description { get; set; }
}
Update ApplicationDbContext to reference the custom ApplicationRole class. For example, the following class references a custom ApplicationUser and a custom ApplicationRole:
using System;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext :
IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Where the last parameter Guid above is the type of the primary key for users and roles, as described here

How to use diffrent DbContext per user in mvc core 2.2

i have some company and many user for that.
now i need to have one database per company.
have to solve this problem in MVC Core. and control DI
You need to create several DataBaseContext classes like this
using Microsoft.EntityFrameworkCore;
namespace Data.Models
{
public class FirstDataContext: DbContext
{
public DbSet<User> Users{ get; set; }
public FirstDataContext(DbContextOptions<FirstDataContext> options)
: base(options)
{
}
}
public class SecondDataContext : DbContext
{
public DbSet<User> Users{ get; set; }
public SecondDataContext(DbContextOptions<SecondDataContext> options)
: base(options)
{
}
}
}
then on appsettings.json add several connection strings that contains address of database
{
"ConnectionStrings": {
"FirstCompany": "Server=(localdb)\\mssqllocaldb;Database=company1;Trusted_Connection=True;"
},
"SecondCompany": "Server=(localdb)\\mssqllocaldb;Database=company2;Trusted_Connection=True;"
},
}
then go to StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
string FirstCompany= Configuration.GetConnectionString("FirstCompany");
string SecondCompany= Configuration.GetConnectionString("SecondCompany");
services.AddDbContext<FirstDataContext>(options =>
options.UseSqlServer(connection));
services.AddDbContext<SecondDataContext>(options =>
options.UseSqlServer(connection));
services.AddMvc();
}
DI:
public class HomeController: Controller
{
FirstDataContext fdcntxt;
SecondDataContext sdcntxt;
public HomeController (FirstDataContext fdcntxt, SecondDataContext sdcntxt)
{
this.fdcntxt = fdcntxt;
this.sdcntxt = sdcntxt;
}
}
I think this should be works).