简体   繁体   English

在 ASP.NET Core API 中使用 DTO 和 AutoMapper 时的 HttpPut

[英]HttpPut when working with DTO and AutoMapper in ASP.NET Core API

In my API project I have Course model such:在我的 API 项目中,我有Course model 这样的:

 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:我想使用HttpPutDTOAutoMapper概念应用于我的更新课程操作,因此我创建了一个CourseUpdateDto DTO,如下所示:

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:这是我的 AutoMapper 配置:

 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.当我使用 Postman 测试此操作时,它返回status of 204但过程没有改变。 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();在映射调用更新方法和调用 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.首先,你需要从你的数据库中获取一个准确的记录(这里我的意思是从DbContext获取它),然后 map 传入数据到你的实体。

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();但我意识到问题可能出在_unitOfWork.SaveChangesAsync(); that used async/await .使用async/await but I didn't define the function as async.但我没有将 function 定义为异步。 So I changed the function to async and add await await _unitOfWork.SaveChangesAsync();所以我将 function 更改为异步并添加 await await _unitOfWork.SaveChangesAsync(); . . Finally, it worked!终于,成功了! Very thanks for your warm support!非常感谢您的热情支持!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM