如何使用 AutoMapper 从 DTO 到 Model both PUT/POST 进行映射?
How to do mapping using AutoMapper from DTO to Model both PUT/POST?
我已经按照从模型到 DTO 的方式完成了 AutoMapper,并且效果很好。
private ApplicationDbContext db = new ApplicationDbContext();
private MapperConfiguration configuration = new MapperConfiguration(cfg =>
cfg.CreateMap<Activity, ActivityDTO>()
.ForMember(dto => dto.OwnerName, conf => conf.MapFrom(ol => ol.User.FirstName + " " + ol.User.LastName))
.ForMember(dto => dto.CategoryName, conf => conf.MapFrom(ol => ol.Category.Name)));
// GET: api/v1/Activities/5
[HttpGet]
[ResponseType(typeof(ActivityDTO))]
[Route("api/v1/Activities/{id}", Name = "GetActivity")]
public async Task<IHttpActionResult> GetActivity(int id)
{
string userId = User.Identity.GetUserId();
var activityDTO = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
if (activityDTO == null)
{
return NotFound();
}
return Ok(activityDTO);
}
然后我不确定如何在为 Put/Post 控制器保存数据之前将此 AutoMapper 从 DTO 返回到模型。处理这个:
activity.CategoryId = category.Id;
activity.Name = activityDTO.Name;
activity.Description = activityDTO.Description;
activity.NoOfMinutes = activityDTO.NoOfMinutes;
activity.DateModified = DateTime.UtcNow;
和
var activity = 新 Activity
{
UserId = 用户Id,
CategoryId = category.Id,
名字=activityDTO.Name,
说明 = activityDTO.Description,
NoOfMinutes = activityDTO.NoOfMinutes,
创建日期 = DateTime.UtcNow,
修改日期 = DateTime.UtcNow
};
// PUT: api/v1/Activities/5
[HttpPut]
[Route("api/v1/Activities/{id}")]
[ResponseType(typeof(void))]
public async Task<IHttpActionResult> PutActivity(int id, ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
if (id != activityDTO.Id)
{
return BadRequest();
}
var activity = await db.Activities.FirstOrDefaultAsync(q => q.Id == id);
if (activity == null)
{
return NotFound();
}
if (userId != activity.UserId)
{
return BadRequest("No right access to update");
}
activity.CategoryId = category.Id;
activity.Name = activityDTO.Name;
activity.Description = activityDTO.Description;
activity.NoOfMinutes = activityDTO.NoOfMinutes;
activity.DateModified = DateTime.UtcNow;
db.Entry(activity).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ActivityExists(id))
{
return NotFound();
}
else
{
return BadRequest("The model is invalid");
}
}
return Ok();
}
// POST: api/Activities
[HttpPost]
[Route("api/v1/Activities")]
[ResponseType(typeof(Activity))]
public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
var activity = new Activity
{
UserId = userId,
CategoryId = category.Id,
Name = activityDTO.Name,
Description = activityDTO.Description,
NoOfMinutes = activityDTO.NoOfMinutes,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow
};
db.Activities.Add(activity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
return BadRequest("The model is invalid");
}
var newActivityDto = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == activity.Id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
}
更新:
private MapperConfiguration configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Activity, ActivityDTO>()
.ForMember(dst => dst.OwnerName, src => src.MapFrom(ol => ol.User.FirstName + " " + ol.User.LastName))
.ForMember(dst => dst.CategoryName, src => src.MapFrom(ol => ol.Category.Name));
cfg.CreateMap<ActivityDTO, Activity>()
.ForMember(dst => dst.UserId, opt => opt.MapFrom(src => HttpContext.Current.User.Identity.GetUserId()))
.ForMember(dst => dst.CategoryId, opt => opt.MapFrom(src => GetCategoryId(HttpContext.Current.User.Identity.GetUserId(), src.CategoryName)))
.ForMember(dst => dst.DateCreated, opt => opt.MapFrom(src => DateTime.UtcNow))
.ForMember(dst => dst.DateModified, opt => opt.MapFrom(src => DateTime.UtcNow));
});
修改POST如下:
// POST: api/Activities
[HttpPost]
[Route("api/v1/Activities")]
[ResponseType(typeof(Activity))]
public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
/*category.UserId = userId,
CategoryId = category.Id,
Name = activityDTO.Name,
Description = activityDTO.Description,
NoOfMinutes = activityDTO.NoOfMinutes,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow
};*/
//var activity = mapper.Map<ActivityDTO, Activity>(activityDTO);
var activity = configuration.CreateMapper().Map<ActivityDTO, Activity>(activityDTO);
db.Activities.Add(activity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
return BadRequest("The model is invalid");
}
var newActivityDto = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == activity.Id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
}
您需要在 MapperConfiguration
中映射您的 add/update DTO
CreateMap<ActivityDTO, Activity>();
CreateMap<ActivityUpdateDTO, Activity>();
然后需要添加mapper
public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
//var activity = new Activity
//{
//UserId = userId,
//CategoryId = category.Id,
//Name = activityDTO.Name,
//Description = activityDTO.Description,
//NoOfMinutes = activityDTO.NoOfMinutes,
//DateCreated = DateTime.UtcNow,
//DateModified = DateTime.UtcNow
//};
var activity = Mapper.Map<ActivityDTO, Activity>(activityDTO);
db.Activities.Add(activity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
return BadRequest("The model is invalid");
}
var newActivityDto = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == activity.Id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
}
去掉这两行
.ForMember(dst => dst.DateCreated, opt => opt.MapFrom(src => DateTime.UtcNow))
.ForMember(dst => dst.DateModified, opt => opt.MapFrom(src => DateTime.UtcNow));
像这样添加你的 DTO
public class ActivityDTO
{
public ActivityDTO()
{
DateCreated = DateTime.UtcNow;
}
public DateTime DateCreated { get; set; }
// other properties
}
public class ActivityUpdateDTO
{
public ActivityUpdateDTO()
{
DateModified = DateTime.UtcNow;
}
public DateTime DateModified { get; set; }
// other properties
}
我已经按照从模型到 DTO 的方式完成了 AutoMapper,并且效果很好。
private ApplicationDbContext db = new ApplicationDbContext();
private MapperConfiguration configuration = new MapperConfiguration(cfg =>
cfg.CreateMap<Activity, ActivityDTO>()
.ForMember(dto => dto.OwnerName, conf => conf.MapFrom(ol => ol.User.FirstName + " " + ol.User.LastName))
.ForMember(dto => dto.CategoryName, conf => conf.MapFrom(ol => ol.Category.Name)));
// GET: api/v1/Activities/5
[HttpGet]
[ResponseType(typeof(ActivityDTO))]
[Route("api/v1/Activities/{id}", Name = "GetActivity")]
public async Task<IHttpActionResult> GetActivity(int id)
{
string userId = User.Identity.GetUserId();
var activityDTO = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
if (activityDTO == null)
{
return NotFound();
}
return Ok(activityDTO);
}
然后我不确定如何在为 Put/Post 控制器保存数据之前将此 AutoMapper 从 DTO 返回到模型。处理这个:
activity.CategoryId = category.Id; activity.Name = activityDTO.Name; activity.Description = activityDTO.Description; activity.NoOfMinutes = activityDTO.NoOfMinutes; activity.DateModified = DateTime.UtcNow;
和
var activity = 新 Activity { UserId = 用户Id, CategoryId = category.Id, 名字=activityDTO.Name, 说明 = activityDTO.Description, NoOfMinutes = activityDTO.NoOfMinutes, 创建日期 = DateTime.UtcNow, 修改日期 = DateTime.UtcNow };
// PUT: api/v1/Activities/5
[HttpPut]
[Route("api/v1/Activities/{id}")]
[ResponseType(typeof(void))]
public async Task<IHttpActionResult> PutActivity(int id, ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
if (id != activityDTO.Id)
{
return BadRequest();
}
var activity = await db.Activities.FirstOrDefaultAsync(q => q.Id == id);
if (activity == null)
{
return NotFound();
}
if (userId != activity.UserId)
{
return BadRequest("No right access to update");
}
activity.CategoryId = category.Id;
activity.Name = activityDTO.Name;
activity.Description = activityDTO.Description;
activity.NoOfMinutes = activityDTO.NoOfMinutes;
activity.DateModified = DateTime.UtcNow;
db.Entry(activity).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ActivityExists(id))
{
return NotFound();
}
else
{
return BadRequest("The model is invalid");
}
}
return Ok();
}
// POST: api/Activities
[HttpPost]
[Route("api/v1/Activities")]
[ResponseType(typeof(Activity))]
public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
var activity = new Activity
{
UserId = userId,
CategoryId = category.Id,
Name = activityDTO.Name,
Description = activityDTO.Description,
NoOfMinutes = activityDTO.NoOfMinutes,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow
};
db.Activities.Add(activity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
return BadRequest("The model is invalid");
}
var newActivityDto = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == activity.Id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
}
更新:
private MapperConfiguration configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Activity, ActivityDTO>()
.ForMember(dst => dst.OwnerName, src => src.MapFrom(ol => ol.User.FirstName + " " + ol.User.LastName))
.ForMember(dst => dst.CategoryName, src => src.MapFrom(ol => ol.Category.Name));
cfg.CreateMap<ActivityDTO, Activity>()
.ForMember(dst => dst.UserId, opt => opt.MapFrom(src => HttpContext.Current.User.Identity.GetUserId()))
.ForMember(dst => dst.CategoryId, opt => opt.MapFrom(src => GetCategoryId(HttpContext.Current.User.Identity.GetUserId(), src.CategoryName)))
.ForMember(dst => dst.DateCreated, opt => opt.MapFrom(src => DateTime.UtcNow))
.ForMember(dst => dst.DateModified, opt => opt.MapFrom(src => DateTime.UtcNow));
});
修改POST如下:
// POST: api/Activities
[HttpPost]
[Route("api/v1/Activities")]
[ResponseType(typeof(Activity))]
public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
/*category.UserId = userId,
CategoryId = category.Id,
Name = activityDTO.Name,
Description = activityDTO.Description,
NoOfMinutes = activityDTO.NoOfMinutes,
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow
};*/
//var activity = mapper.Map<ActivityDTO, Activity>(activityDTO);
var activity = configuration.CreateMapper().Map<ActivityDTO, Activity>(activityDTO);
db.Activities.Add(activity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
return BadRequest("The model is invalid");
}
var newActivityDto = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == activity.Id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
}
您需要在 MapperConfiguration
中映射您的 add/update DTOCreateMap<ActivityDTO, Activity>();
CreateMap<ActivityUpdateDTO, Activity>();
然后需要添加mapper
public async Task<IHttpActionResult> PostActivity(ActivityDTO activityDTO)
{
string userId = User.Identity.GetUserId();
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var category = db.Categories.SingleOrDefault(x => x.UserId == userId && x.Name == activityDTO.CategoryName);
if (category == null)
{
return BadRequest("Category not valid.");
}
//var activity = new Activity
//{
//UserId = userId,
//CategoryId = category.Id,
//Name = activityDTO.Name,
//Description = activityDTO.Description,
//NoOfMinutes = activityDTO.NoOfMinutes,
//DateCreated = DateTime.UtcNow,
//DateModified = DateTime.UtcNow
//};
var activity = Mapper.Map<ActivityDTO, Activity>(activityDTO);
db.Activities.Add(activity);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException)
{
return BadRequest("The model is invalid");
}
var newActivityDto = await db.Activities
.Include(b => b.User)
.Include(c => c.Category)
.Where(q => q.UserId == userId && q.Id == activity.Id)
//.Select(AsActivityDto)
.ProjectTo<ActivityDTO>(configuration)
.FirstOrDefaultAsync();
return CreatedAtRoute("GetActivity", new { id = newActivityDto.Id }, newActivityDto);
}
去掉这两行
.ForMember(dst => dst.DateCreated, opt => opt.MapFrom(src => DateTime.UtcNow))
.ForMember(dst => dst.DateModified, opt => opt.MapFrom(src => DateTime.UtcNow));
像这样添加你的 DTO
public class ActivityDTO
{
public ActivityDTO()
{
DateCreated = DateTime.UtcNow;
}
public DateTime DateCreated { get; set; }
// other properties
}
public class ActivityUpdateDTO
{
public ActivityUpdateDTO()
{
DateModified = DateTime.UtcNow;
}
public DateTime DateModified { get; set; }
// other properties
}