Home > Back-end >  PUT request with without every field from the DTO model
PUT request with without every field from the DTO model

Time:12-20

I want to make PUT request in ASP .NET CORE that user can make to update his note. It's my UpdateNoteDTO:

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

and it's my Update method:

        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();
        }

I want to make request that user can make to change single field without need for declare all of them. This code what i wrote is working but i bet there is better solution for this :D

CodePudding user response:

The way you are doing it looks fine but I would suggest two changes,

  1. If you plan to use the endpoint for updating one or some values it's better to change request type to PATCH, the HTTP PATCH request method applies partial modifications to a resource whereas HTTP PUT changes whole resource.
  2. To easily add conditions for mapping DTOs to entity models I would rather use Automapper which allows user to declare mapping conditions in a single spot and use IMapper interface to map the models. For example if you have two classes:
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; }
}

you can map them by creating a mapping profile with conditions instead of using if, switch or any other way of comparing whether to map or not

mapping Profile could look like this:

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());  
    }
}

and update the Update(UpdateNoteDto dto, int noteID) function correspondingly:

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();
}

CodePudding user response:

This case should be handled by the client

Or

if you want only a some value to be edited, it is better to use PATCH

If the client wants the previous data not to be edited It should send you the previous data

Maybe, for example, the user wants to field the "NoteBody" value as empty In which case it cannot do this

  • Related