ASP.NET将多个DTO转换为一个模型,并在DTO内部进行验证



在我的web应用程序中,我有一个具有许多属性的类。用户可以通过一堆选择框来修改这些属性,每个选择框负责一个属性。每次更改给定属性时,都会触发更改事件,ajax会将此属性的新值发送到Controller中的Update方法。

到目前为止,我有一个UpdateDto,它由可为null的字段组成。在我的更新控制器中,我检查每个DTO的字段是否为空。若它不为null,则表示用户想要更改此属性,并将其更新并保存在数据库中。

不幸的是,Update方法的代码对我来说有点难看。它检查每个属性,而且很长。看看:

控制器中的更新方法:

public IHttpActionResult UpdateScrumTask(int id, ScrumTaskDetailsDto scrumTaskDto)
{
var scrumTaskFromDb = _context.ScrumTasks
.SingleOrDefault(s => s.Id == id);
if (scrumTaskFromDb == null)
return NotFound();
if (!ModelState.IsValid)
return BadRequest();
if (!string.IsNullOrWhiteSpace(scrumTaskDto.UserId))
{
var user = _context.Users
.SingleOrDefault(u => u.Id.Equals(scrumTaskDto.UserId));
scrumTaskFromDb.UserId = user?.Id;
}
else if (scrumTaskDto.EstimationId != null)
{
var estimation = _context.Estimations
.SingleOrDefault(u => u.Id == scrumTaskDto.EstimationId.Value);
scrumTaskFromDb.EstimationId = estimation?.Id;
}
else if (scrumTaskDto.Priority != null)
{
if (scrumTaskDto.Priority.Value == 0)
scrumTaskDto.Priority = null;
scrumTaskFromDb.Priority = scrumTaskDto.Priority;
}
else if (scrumTaskDto.TaskType != null)
{
scrumTaskFromDb.TaskType = scrumTaskDto.TaskType.Value;
}
_context.SaveChanges();
return Ok();
}

更新DTO:

public class ScrumTaskDetailsDto
{    
public int? EstimationId { get; set; }
[Range(0, 5)]
public byte? Priority { get; set; }
[Range(0, 2)]
public TaskType? TaskType { get; set; }
public string UserId { get; set; }
}

请注意,这些属性在数据库中也可以为null。这就是为什么,例如,如果找不到UserId,则数据库中的属性将设置为null。

我想知道它应该是什么样子。什么是更好的解决方案?

  • 保留一个Update方法,并使用一个UpdateDto与多个可为null的字段OR
  • 将Update方法设计为多个方法,每个方法负责一个属性并创建单独的DTO。它带来了将有许多DTO与一个具有单一属性的模型连接(这好吗?)

另一个问题是:我应该在DTO中使用validtion(DataAnnotation)吗?如果没有,替代方案是什么?

我建议几个改进:

  1. 使用存储库模式或使用MediatR之类的库的查询和命令对象,将查询逻辑与核心业务逻辑分离,并且控制器只应调用其他方法为其做一些事情并返回响应,它不应具有任何查询或任何其他逻辑
  2. DTO在我看来还可以,只要它围绕着一个特定的任务
  3. 我肯定会把更新和控制器分开,因为它是一个或多个方法,有35…行,这并不理想,也许你可以把它分成两个方法,一个负责验证,一个用于实际更新,你也可以使用依赖注入将更新和验证方法与控制器解耦

相关内容

最新更新