am a beginner in ASP.NET Core. I am creating a Web API service. While I am fetching the data from the database, I had a problem. What is the error I got? I have successfully done the database migration part and created the database successfully.
StudentDbContext is null
StudentController
namespace webb.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StudentController : ControllerBase
{
private StudentDbContext studentDbContext;
public StudentController(StudentDbContext studentDbContext)
{
studentDbContext = studentDbContext;
}
// GET: api/<EmployeeController>
[HttpGet]
public IEnumerable<Student> Get()
{
// var studens = studentDbContext.Student;
return studentDbContext.Student;
}
}
}
Model
public class Student
{
public int id { get; set; }
public string stname { get; set; }
public string course { get; set; }
}
}
StudentDbContext
public class StudentDbContext : DbContext
{
public StudentDbContext(DbContextOptions<StudentDbContext> options) : base(options)
{
}
public DbSet<Student> Student { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=.;Initial Catalog=ams;Integrated Security=True; TrustServerCertificate = True");
}
}
IDataService
public interface IDataService<T>
{
Task<IEnumerable<T>> GetAll();
Task<T> Get(int id);
Task<T> Create(T entity);
Task<bool> Delete(T entity);
Task<T> Update(T entity);
}
}
I have successfully done the database migration part and created the
database successfully. StudentDbContext is null
Well, two mistake has been done. Your model has no primary key. So you will always get null data when there is no primary key set to your table column.
Therefore, your model should be as following:
Model:
public class Student
{
[Key]
public int id { get; set; }
public string stname { get; set; }
public string course { get; set; }
}
Controller:
Another misake is here studentDbContext.Student; this will not bring anything. You would be liking to fetch student list instead. So you should write studentDbContext.Student.ToList();. As following"
[HttpGet]
public IEnumerable<Student> Get()
{
// var studens = studentDbContext.Student;
return studentDbContext.Student.ToList();
}
Note: In addition, your constructor convension is not correct, it can be written as following:
[Route("api/[controller]")]
[ApiController]
public class StudentController : ControllerBase
{
private readonly StudentDbContext _studentDbContext;
public StudentController(ApplicationDbContext studentDbContext)
{
_studentDbContext = studentDbContext;
}
// GET: api/<EmployeeController>
[HttpGet]
public IEnumerable<Student> Get()
{
// var studens = studentDbContext.Student;
return _studentDbContext.Student.ToList();
}
}
Note: You can check more details on asp.net core web api official document here
Output:
For further details you can have a look on official document here.
Related
I'm new to ASP.NET Core and I have built an ASP.NET Core MVC with EF Core appplication using Code First approach when creating the database.
Now, I want to use DTOs and AutoMapper in this simple app.
In the code below you may find the Employee.cs from Models folder:
public class Employee
{
[Key]
public int EmployeeId { get; set; }
[Column(TypeName ="nvarchar(250)")]
[Required(ErrorMessage ="This field is required.")]
[DisplayName("Full Name")]
public string FullName { get; set; }
[Column(TypeName = "varchar(10)")]
[DisplayName("Emp. Code")]
public string EmpCode { get; set; }
[Column(TypeName = "varchar(100)")]
public string Position { get; set; }
[Column(TypeName = "varchar(100)")]
[DisplayName("Office Location")]
public string OfficeLocation { get; set; }
}
Below you may find the EmployeeController.cs file:
public class EmployeeController : Controller
{
private readonly EmployeeContext _context;
public EmployeeController(EmployeeContext context)
{
_context = context;
}
// GET: Employee
public async Task<IActionResult> Index()
{
return View(await _context.Employees.ToListAsync());
}
// GET: Employee/Create
public IActionResult AddOrEdit(int id = 0)
{
if (id == 0)
return View(new Employee());
else
return View(_context.Employees.Find(id));
}
// POST: Employee/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddOrEdit([Bind("EmployeeId,FullName,EmpCode,Position,OfficeLocation")] Employee employee)
{
if (ModelState.IsValid)
{
if (employee.EmployeeId == 0)
_context.Add(employee);
else
_context.Update(employee);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(employee);
}
// GET: Employee/Delete/5
public async Task<IActionResult> Delete(int? id)
{
var employee =await _context.Employees.FindAsync(id);
_context.Employees.Remove(employee);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
}
Additionally, you may find below the Startup.cs file:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<EmployeeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DevConnection")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Employee}/{action=Index}/{id?}");
});
}
}
What changes should I make to my app in order to use DTOs and AutoMapper?
Please let me know whether you need other files from the app.
Thanks.
You can do following steps.
Create your EmployeeDTO.cs
public class EmployeeDTO
{
public int EmployeeId { get; set; }
public string FullName { get; set; }
public string EmpCode { get; set; }
public string Position { get; set; }
public string OfficeLocation { get; set; }
}
Install the corresponding NuGet package
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
Note : If we install the AutoMapper.Extensions.Microsoft.DependencyInjection package, it will automatically install the AutoMapper package for us since it references it.
Create MappingProfile.cs
Add using AutoMapper;
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Employee, EmployeeDTO>();
CreateMap<EmployeeDTO, Employee>();
}
}
Configure the services. Let’s do it in the Startup.cs class.
services.AddAutoMapper(typeof(Startup));
First, we inject the mapper object into the controller. Then, we call the Map()method, which maps the Employee object to the EmployeeDTO object.
public class EmployeeController : Controller
{
private readonly EmployeeContext _context;
private readonly IMapper _mapper;
public EmployeeController(EmployeeContext context,, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
// GET: Employee
public async Task<IActionResult> Index()
{
List<EmployeeDTO> employees = _mapper.Map<List<Employee>, List<EmployeeDTO>>(await _context.Employees.ToListAsync());
return View(employees);
}
}
I am trying to use MVC with a controller a view a model and the database.
But I premise I do not know how to use entity framework in my case to connect the model and the database. So I get this runtime error:
"InvalidOperationException: Unable to resolve service for type 'WebCoreFly.Models.FlightsList' while attempting to activate 'WebCoreFly.Controllers.HomeController"
My code consists in:
the controller code:
public class HomeController : Controller
{
private FlightsList l;
public HomeController(FlightsList theList)
{ l = theList; }
public ViewResult Index()
{
return View(l.Flights);
}
}
the Model Code for Flights:
public partial class Flights
{
public long ID { get; set; }
public long Id_Destination { get; set; }
public string Id_Source { get; set; }
public string Nome { get; set; }
public string Company { get; set; }
public System.DateTime Time { get; set; }
public string Id_Plane { get; set; }
public Nullable<System.DateTime> TimeOfArrival { get; set; }
}
and the model for FlightsList:
public class FlightsList
{
private FlyDBContext context;
public FlightsList(FlyDBContext ctx)
{
context = ctx;
}
public IQueryable<Flights> Flights => context.Flights;
}
finally I have defined my dbcontext:
public class FlyDBContext : DbContext
{
public FlyDBContext(DbContextOptions<FlyDBContext> options)
: base(options)
{
}
public DbSet<WebCoreFly.Models.Passengers> Passengers { get; set; }
public DbSet<WebCoreFly.Models.Bookings> Bookings { get; set; }
public DbSet<WebCoreFly.Models.Flights> Flights { get; set; }
}
And in my startup code, I configure services to accept my dbcontext with a link to Existing SQL Database called Fly:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<FlyDBContext>(options =>
options.UseSqlServer(#"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Fly;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"));
}
And this is the Configure method of startup:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
My question is: who is responsible to pass to my controller the flights list? and since the flightlist is tied to the dbcontext, is the problem somehow related to the fact I did not use entityframework? (For semplicity Idid not post the code for my view, but I can do it if necessary)
the issue is coming because of the dependency Injection. Here How the application would know that Flights List object requires in Home Controller. To fix this you have to configure it in StartUp.Cs class Configure Service method.
services.AddSingelton<FlightsList>();
There are various ways to configure it like Transient, AddScoped etc.
It is better if you use repository pattern here. Register here the Interface. like following.
services.AddSingelton<IRepository, FlightsList>();
In controller side.
public class HomeController : Controller
{
private IRepository l;
public HomeController(IRepository theList)
{ l = theList; }
public ViewResult Index()
{
return View(l.Flights);
}
}
Hope it will help.
I am having problems loading a entity that I have assigned to the ApplicationUser in my .NET core MVC application.
I have added one of my entities to the user class, see code below:
public class ApplicationUser : IdentityUser
{
public int? AzureBlobResourceId { get; set; }
[ForeignKey("AzureBlobResourceId")]
public AzureBlobResource AzureBlobResource { get; set; }
}
Ideally I want the AzureBlobResource object to be loaded when retrieving the user from the UserManager
private Task<ApplicationUser> GetCurrentUserAsync()
{
return _userManager.GetUserAsync(HttpContext.User);
}
Unfortunately though the AzureBlobResource object always is null, even when the AzureBlobResourceId has a value.
What am I missing here?
Thanks, Nikolai
You need to implement your userstore
public class ApplicationUser : IdentityUser {
public int? AzureBlobResourceId { get; set; }
[ForeignKey("AzureBlobResourceId")]
public AzureBlobResource AzureBlobResource { get; set; }
}
public class MyAppUserStore : UserStore<ApplicationUser>
{
public MyAppUserStore(DbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
{
}
public override async Task<ApplicationUser> FindByIdAsync(string userId, CancellationToken cancellationToken = new CancellationToken())
{
return await Context.Set<ApplicationUser>().Include(p => p.AzureBlobResource).FirstOrDefaultAsync(u => u.Id == userId, cancellationToken: cancellationToken);
}
}
And in Sturtup.cs add
ervices.AddIdentity<ApplicationUser, IdentityRole>()
.AddUserStore<MyAppUserStore >()
.AddUserManager<UserManager<ApplicationUser>>()
.AddDefaultTokenProviders();
I Have a PhoneBook Project in MVC and use IUnitOfWork .
but I dont Know that How do this project.
the link of the project :
http://www.mediafire.com/download/jy0b5ins5eisy5t/MvcAppPhoneBook.rar
please complate thie project for me
i'm doing CRUD in this project.
I've used generic repo and UoW in my projects as below. You can take reference of this to complete your project. I usually have 4 layer solution architecture:
Core
Model classes
Data
Generic Repo and UoW
DbContext
Code first migrations
Web
applications solution with dependency injection implementation (e.g.Ninject)
Test
Model classes
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Course
{
public int Id { get; set; }
public string Name { get; set; }
}
MyDbContext.cs:
public class MyDbContext : DbContext
{
public MyDbContext() : base("name=DefaultConnection”)
{
}
public System.Data.Entity.DbSet<User> Users { get; set; }
public System.Data.Entity.DbSet<Course> Courses { get; set; }
}
Unit of Work:
public class UnitOfWork : IUnitOfWork
{
//private variable for db context
private MyDbContext _context;
//initial db context variable when Unit of Work is constructed
public UnitOfWork()
{
_context = new MyDbContext();
}
//property to get db context
public MyDbContext Context
{
//if not null return current instance of db context else return new
get { return _context ?? (_context = new MyDbContext()); }
}
//save function to save changes using UnitOfWork
public void Save()
{
_context.SaveChanges();
}
}
Generic Repository:
public class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected readonly IUnitOfWork _unitOfWork;
private readonly IDbSet<T> _dbSet;
public RepositoryBase(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_dbSet = _unitOfWork.Context.Set<T>();
}
public virtual void Save()
{
_unitOfWork.Save();
}
public virtual void Add(T entity)
{
_dbSet.Add(entity);
_unitOfWork.Save();
}
//Similarly you can have Update(), Delete(), GetAll() implementation here
}
Entity Repository inheriting from generic repo:
public class UserRepository:RepositoryBase<User>,IUserRepository
{
public UserRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
//Here you can also define functions specific to User
}
controller.cs
public class UserController : Controller
{
private readonly IUserRepository _dbUserRepository;
public UserController(IUserRepository dbUserRepository)
{
_dbUserRepository = dbUserRepository;
}
// GET: /User/
public ActionResult Index()
{
var users = _dbUserRepository.GetAll();
return View(users.ToList());
}
//Other CRUD operations
}
I have 10 tables with the same design. Each of them have an IsActive column.
For example:
Category
CatID
CatName
IsActive
Product
PrdID
PrdName
IsActive
Is there a way to create a generic method to update the IsActive column.
public void Deactivate<T>(T TEntity)
{
// Put the code to update
// IsActive
}
I read about generic repository, but nothing explains how to update a specific column.
Thanks everyone.
The trick is to put a where type restriction for your generic type on your BaseRepository class. Try something similar to this:
WARNING: air code ;-)
Base model:
public interface IDbTable
{
bool IsActive { get; set; }
}
public class DbTable
{
public bool IsActive { get; set; }
}
Your model
public class Category : DbTable
{
public int CatId { get; set; }
public string CatName { get; set; }
}
public class Product : DbTable
{
public int PrdId { get; set; }
public string PrdName { get; set; }
}
Your repository
public interface IBaseRepository<T> where T : class, IDbTable
{
void Deactivate<T>(T entity);
}
public class BaseRepository<T> : IBaseRepository
{
public void Deactivate<T>(T entity)
{
entity.IsActive = false;
}
}
You could go even further and extend your IDbTable to include even more generic and helpful columns. E.g.
public interface IDbTable
{
int Id { get; set; }
bool IsActive { get; set; }
DateTime UpdatedOn { get; set; }
DateTime CreatedOn { get; set; }
}
Repo
public interface IBaseRepository<T> where T : class, IDbTable
{
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Deactivate(T entity);
}
public class BaseRepository<T> : IBaseReposiotry<T>
{
public T GetById(int id)
{
//code to get the entity by id
}
public void Add(T entity)
{
entity.CreatedOn = DateTime.UtcNow;
entity.UpdatedOn = DateTime.UtcNow;
}
public void Update(T entity)
{
entity.UpdatedOn = DateTime.UtcNow;
}
public void Deactivate(T entity)
{
entity.IsActive = false;
}
}
These two articles should help you out as well:
new Repository().DoMagic()
Implementing a Simple Generic Repository with LinqToSql
HTHs,
Charles