Using asp net mvc what’s the best practice for creating an action that allows to create a new project whose owner is the current logged user?
// Entities
class User {
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
class Project {
[Key]
public int Id { get; set; }
public string Name { get; set; }
[Required]
public int OwnerId;
[ForeignKey("OwnerId")]
public User Owner? { get; set; }
}
// DTO / ModeView
class ProjectModelView {
public string Name;
}
class ProjectController : Controller {
private readonly ApplicationDbContext _context;
public ProjectController(ApplicationDbContext context) {
_context = context;
}
public IActionResult Create([Bind("Name")] Project project) {
return View();
}
// 1. Using the model directly
[HttpPost]
public IActionResult Create([Bind("Name")] Project project) {
project.Owner = Session.UserId;
if (ModelState.IsValid) {
_context.Projects.Add(project);
_context.SaveChanges();
return RedirectToAction(actionName: "Index");
}
return View(project);
}
// 2. Using a dto/model view (not sure if this is considerer a model view in this case)
[HttpPost]
public IActionResult Create(ProjectModelView project) {
if (ModelState.IsValid) {
_context.Projects.Add(new Project {
OwnerId = User,
Name = project.name
});
_context.SaveChanges();
return RedirectToAction(actionName: "Index");
}
return View(project);
}
}
I looked up the asp .net documentation and I couldn’t find a correct answer.
Which is more "ASP like" and correct option? Is there better ways to do it? Also, is the dto a ViewModel in this case?
2
Answers
I can suggest you this improvements, hope it helps:
Example: https://medium.com/dotnet-hub/use-mediatr-in-asp-net-or-asp-net-core-cqrs-and-mediator-in-dotnet-how-to-use-mediatr-cqrs-aspnetcore-5076e2f2880c
Example: https://code-maze.com/automapper-net-core/
Check the actor role: https://www.syncfusion.com/succinctly-free-ebooks/akka-net-succinctly/actors-in-asp-net-core
However I’m not sure that your question are still exists when you do a little refactoring from 1 and 2
I use the
Repository/Service pattern
, togeter withN-tier architecture
.N-tier architecture
looks like thisProjectName.Web/Server
, depending if youre making like anmvc application
, then its.Web
, if just aweb api
, then.Server
This is the main project with
controllers, automapper, views
etc.Then three
class libraries projects
ProjectName.Business
, this projects is used to store most of thehelper
logic and diffrent kind ofbusiness logic
for your application, also theDTOs
orViewModels
ProjectName.DataAccess
, data access is the project with the direct connection to thedatabase
, this is the place where I use myrepository folder
with thecontext
method, likeput, get, post
etc. Also theDbContext
ProjectName.Models
, this project is pretty simple, it is just used for all theentities/models
you’re going to useSo how is all this connected?
The projects need
project references.
This is how it will go
.Models
>.DataAccess
>.Business
>.Web/Server
It goes from the bottom to the top, with the
Web/Server project
as the top since this is thereal application.
So how do I implement the
repository pattern
into theN-Tier architecture
?I Create a
Repository folder
in the.DataAccess project.
Inside the repository create the files, for exempel if you have a model and
controller
calledEmployeeController.cs
andEmployee.cs
Then inside the
Repository folder
, to keep it clean – create a sub folder, simply calledEmployee
. Inside theEmployee folder
, create 2 files.EmployeeRepository.cs
andIEmployeeRepository.cs
Inside the
EmployeeRepository
you need a reference toIEmployeeRepository
so your functions and methods will be available to other files.And then just create all the context logic in the repository files.
To keep another layer between the
.Web/Server
project and the database, I Create a folder inside of the.Business project
, calledService
. This is the same principle as theRepository
, create a sub folder calledEmployee
, withEmployeeService.cs
andIEmployeeService.cs
, call all of the methods from the repository to the service, and then you call the service methods from theIEmployeeService
to theEmployeeController
inside of the.Web/Server
project, usingdependency injection
.And there you have it, complete isolation from the dbcontext in the controllers.