关注点分离的 MVC 最佳实践
MVC best practice for seperation of concerns
我正在使用 MVC5 制作网站。
我正在使用脚手架从我的模型生成我的控制器-class。每当它创建控制器的脚手架时,数据库连接和模型操作都会在控制器内发生class(见下文)。通过查看此 thread,我可以看出大多数人都同意这应该发生在模型 class 中。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Username")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
与其让控制器执行此操作,不如让它看起来像这样?:
用户控制器
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Username")] User user)
{
if (ModelState.IsValid)
{
UserModel userModel = new userModel();
userModel.editUser(user);
return RedirectToAction("Index");
}
return View(user);
}
用户模型
public void editUser(User user){
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
}
要指定 "db" 是什么,它将是对我的数据库上下文的引用。
我认为您误解了您引用的答案 (In a MVC application, should the controller or the model handle data access?) 中 "Model" 的含义。
tereško 的回答是:
The business logic in MVC and MVC-inspired patterns has to be in the model layer. And yes, model is supposed to be a layer, not a class or object.
所以不要将数据库访问权限放入您的 ViewModel。相反,您需要业务层中的服务 class 进行数据库访问并将数据库实体映射到数据传输对象或 ViewModel。请注意我如何使用 Command 和 Query classes 将对业务层的访问与任何前端 classes 分离,例如 ViewModels(使用 AutoMapper 在 DTO <-> ViewModel <-> Command/Query).
public interface IUserService {
public UserDto CreateUser(CreateUserCommand command);
public UserDto EditUser(EditUserCommand command);
public void DeleteUser(DeleteUserCommand command);
public UserDto[] FindUsers(FindUsersQuery query);
}
控制器使用此业务层:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(UserViewModel postData) {
if (!ModelState.IsValid) {
return View("Edit", postData);
}
var command = Mapper.Map<EditUserCommand>(postData);
var updatedUserDto = _userService.EditUser(command);
var updatedUserViewModel = Mapper.Map<UserViewModel>(updatedUserDto);
return View("Show", updatedUserViewModel);
}
我正在使用 MVC5 制作网站。
我正在使用脚手架从我的模型生成我的控制器-class。每当它创建控制器的脚手架时,数据库连接和模型操作都会在控制器内发生class(见下文)。通过查看此 thread,我可以看出大多数人都同意这应该发生在模型 class 中。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Username")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(user);
}
与其让控制器执行此操作,不如让它看起来像这样?:
用户控制器
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Username")] User user)
{
if (ModelState.IsValid)
{
UserModel userModel = new userModel();
userModel.editUser(user);
return RedirectToAction("Index");
}
return View(user);
}
用户模型
public void editUser(User user){
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
}
要指定 "db" 是什么,它将是对我的数据库上下文的引用。
我认为您误解了您引用的答案 (In a MVC application, should the controller or the model handle data access?) 中 "Model" 的含义。
tereško 的回答是:
The business logic in MVC and MVC-inspired patterns has to be in the model layer. And yes, model is supposed to be a layer, not a class or object.
所以不要将数据库访问权限放入您的 ViewModel。相反,您需要业务层中的服务 class 进行数据库访问并将数据库实体映射到数据传输对象或 ViewModel。请注意我如何使用 Command 和 Query classes 将对业务层的访问与任何前端 classes 分离,例如 ViewModels(使用 AutoMapper 在 DTO <-> ViewModel <-> Command/Query).
public interface IUserService {
public UserDto CreateUser(CreateUserCommand command);
public UserDto EditUser(EditUserCommand command);
public void DeleteUser(DeleteUserCommand command);
public UserDto[] FindUsers(FindUsersQuery query);
}
控制器使用此业务层:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(UserViewModel postData) {
if (!ModelState.IsValid) {
return View("Edit", postData);
}
var command = Mapper.Map<EditUserCommand>(postData);
var updatedUserDto = _userService.EditUser(command);
var updatedUserViewModel = Mapper.Map<UserViewModel>(updatedUserDto);
return View("Show", updatedUserViewModel);
}