skip to Main Content

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


  1. 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

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search