Home > Mobile >  ASP.NET MVC - What's the best way to store objects on POST/PUT (Architecture)
ASP.NET MVC - What's the best way to store objects on POST/PUT (Architecture)

Time:06-19

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?

CodePudding user response:

I can suggest you this improvements, hope it helps:

  1. Do not inject your db context into controllers - it is bad practise. What if your controller's methods will contain a lot of logic? And what if two controllers has similar methods with similar algorithm? You can add MediatR library with commands and handlers, and in handlers you can use you db context logic. 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
  2. No dto is not view class, you should split domain objects and view objects, you can look to Mapper Example: https://code-maze.com/automapper-net-core/
  3. About your question: 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

CodePudding user response:

I use the Repository/Service pattern, togeter with N-tier architecture.

N-tier architecture looks like this

ProjectName.Web/Server, depending if youre making like an mvc application, then its .Web, if just a web 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 the helper logic and diffrent kind of business logic for your application, also the DTOs or ViewModels

ProjectName.DataAccess, data access is the project with the direct connection to the database, this is the place where I use my repository folder with the context method, like put, get, post etc. Also the DbContext

ProjectName.Models, this project is pretty simple, it is just used for all the entities/models you're going to use

So 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 the real application.

So how do I implement the repository pattern into the N-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 called EmployeeController.cs and Employee.cs Then inside the Repository folder, to keep it clean - create a sub folder, simply called Employee. Inside the Employee folder, create 2 files. EmployeeRepository.cs and IEmployeeRepository.cs Inside the EmployeeRepository you need a reference to IEmployeeRepository 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, called Service. This is the same principle as the Repository, create a sub folder called Employee, with EmployeeService.cs and IEmployeeService.cs, call all of the methods from the repository to the service, and then you call the service methods from the IEmployeeService to the EmployeeController inside of the .Web/Server project, using dependency injection.

And there you have it, complete isolation from the dbcontext in the controllers.

  • Related