In my API project I have Course
model such:
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CourseId { get; set; }
public string CourseName { get; set; }
[ForeignKey("Department")]
public int DepartmentId { get; set; }
public Department Department { get; set; }
public ICollection<CourseEnrollment> CourseEnrollments { get; set; }
public ICollection<CourseAssignment> CourseAssignments { get; set; }
}
I want to applied the DTO
and AutoMapper
concepts to my update course action using HttpPut
, so I created a CourseUpdateDto
DTO such:
public class CourseUpdateDTO
{
[Required]
public int CourseId { get; set; }
[Required, MaxLength(100)]
public string CourseName { get; set; }
[Required]
public int DepartmentID { get; set; }
}
This is my AutoMapper configuration:
CreateMap<CourseUpdateDTO, Course>()
.ForMember(dest => dest.CourseId,
opts => opts.MapFrom(src => src.CourseId))
.ForMember(dest => dest.CourseName,
opts => opts.MapFrom(src => src.CourseName))
.ForMember(dest => dest.DepartmentId,
opts => opts.MapFrom(src => src.DepartmentID));
And finally this is my trial to update course:
[HttpPut("{id:int}")]
public ActionResult PutCourse(int id, [FromBody] CourseUpdateDTO courseDto)
{
if (courseDto is null)
{
return BadRequest();
}
var entity = new Course
{
CourseId = id,
CourseName = courseDto.CourseName,
DepartmentId = courseDto.DepartmentID
};
_mapper.Map(courseDto, entity);
try
{
_unitOfWork.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
ModelState.AddModelError(nameof(PutCourse), "unable to save changes");
return StatusCode(500, ModelState);
}
return NoContent();
}
When I tested this action using Postman, it returned status of 204
But the course has not changed. Am I wrong anywhere? Im new to this concept so hope someone configure that out to me.
You didn't call the update method before saving. After mapping call update method and after call SaveChangesAsync();
First of all, you need to get an exact record from your database (here I mean get it from DbContext
), then map incoming data to your entity.
To make it works, you have to apply some changes like below:
var entity=_context.Cources.SingleOrDefault(x=>x.Id=id);
// check if it is not null
_mapper.Map(courseDto, entity);
_context.Entity(entity).Status = Status.Modified;
_context.SaveChangesAsync();
After got some suggestions from people in this post. I've changed the original action
[HttpPut("{id:int}")]
public ActionResult PutCourse(int id, [FromBody] CourseUpdateDTO courseDto)
{
if (courseDto is null)
{
return BadRequest();
}
var entity = new Course
{
CourseId = id,
CourseName = courseDto.CourseName,
DepartmentId = courseDto.DepartmentID
};
_mapper.Map(courseDto, entity);
try
{
_unitOfWork.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
ModelState.AddModelError(nameof(PutCourse), "unable to save changes");
return StatusCode(500, ModelState);
}
return NoContent();
}
to this
[HttpPut("{id:int}")]
public async Task<ActionResult> PutCourse(int id, [FromBody] CourseUpdateDTO courseDto)
{
if (courseDto is null)
{
return BadRequest();
}
var entity = _unitOfWork.CourseService.Get(id);
if (entity is null)
{
return NotFound();
}
_mapper.Map(courseDto, entity);
try
{
_unitOfWork.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
ModelState.AddModelError(nameof(PutCourse), "unable to save changes");
return StatusCode(500, ModelState);
}
return NoContent();
}
However, it still doesn't work. But I realized the problem might be in the _unitOfWork.SaveChangesAsync();
that used async/await
. but I didn't define the function as async. So I changed the function to async and add await await _unitOfWork.SaveChangesAsync();
. Finally, it worked! Very thanks for your warm support!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.