不包含DTO模型中的每个字段的PUT请求



我想在asp.net CORE中提出PUT请求,用户可以更新他的笔记。它是我的UpdateNoteDTO:

public class UpdateNoteDto
{
[MaxLength(50)]
public string NoteTitle { get; set; }
[MaxLength(500)]
public string NoteBody { get; set; }
public int Color { get; set; }
}

它是我的更新方法:

public void Update(UpdateNoteDto dto, int noteID)
{
var note = _dbContext
.Notes
.FirstOrDefault(r => r.Id == noteID);

if (note is null)
{
throw new NotFoundException("Note not found");
}
note.NoteTitle = dto.NoteTitle == string.Empty
|| dto.NoteTitle is null 
? note.NoteTitle : dto.NoteTitle;
note.NoteBody = dto.NoteBody == string.Empty 
|| dto.NoteBody is null 
? note.NoteBody : dto.NoteBody;
note.Color = dto.Color == 1 ? note.Color : dto.Color;
_dbContext.SaveChanges();
}

我想请求用户可以改变单个字段,而不需要声明所有字段。这段代码我写的是工作,但我打赌有更好的解决方案:D

你这样做的方式看起来很好,但我建议两个改变,

  1. 如果您计划使用端点更新一个或一些值,最好将请求类型更改为PATCH, HTTP PATCH请求方法对资源进行部分修改,而HTTP PUT则更改整个资源。
  2. 为了方便地添加映射dto到实体模型的条件,我宁愿使用Automapper,它允许用户在单个点声明映射条件,并使用IMapper接口映射模型。例如,如果你有两个类:
public class UpdateNoteDto
{
[MaxLength(50)]
public string NoteTitle { get; set; }
[MaxLength(500)]
public string NoteBody { get; set; }
public int Color { get; set; }
}

public class Note
{
public int Id { get; set; }
public string NoteTitle { get; set; }
public string NoteBody { get; set; }
public int Color { get; set; }
}

您可以通过创建带有条件的映射配置文件来映射它们,而不是使用if, switch或任何其他比较是否映射的方法

映射配置文件可以像这样:

public class NoteProfile: Profile
{
public NoteProfile()
{
CreateMap<UpdateNoteDto, Note>()  
.ForMember(dest => dest.NoteTitle, opt => opt.Condition(src => !string.IsNullOrEmpty(src.NoteTitle)))  
.ForMember(dest => dest.NoteBody, opt => opt.Condition(src => !string.IsNullOrEmpty(src.NoteBody)))  
.ForMember(dest => dest.Color, opt => opt.Condition(src => src.Color != default))  
.ForMember(dest => dest.Id, opt => opt.Ignore());  
}
}

,并相应地更新Update(UpdateNoteDto dto, int noteID)函数:

public void Update(UpdateNoteDto dto, int noteID)
{
var noteToUpdate = _dbContext
.Notes
.FirstOrDefault(r => r.Id == noteID);
if (note is null)
{
throw new NotFoundException("Note not found");
}
var note = _mapper.Map(dto, note);
_dbContext.Update(note);
_dbContext.SaveChanges();
}

client应该处理这个问题

如果你想更新一个实体,最好使用PATCH

如果客户端希望之前的数据不被编辑它应该发送查看之前的数据

也许,例如,用户想要输入"notebody";在这种情况下,它不能这样做

最新更新