【发布时间】:2017-06-02 12:40:03
【问题描述】:
我正在使用 AutoMapper 在我的 DTO 和业务对象之间进行映射。这很好用。
但是,我有一个 Web API,它接受 PUT 请求以更新实体。动作如下所示:
public virtual async Task<IHttpActionResult> Put(string id, [FromBody] ProjectDto projectDto)
当从 ProjectDto 映射到 Project(业务对象)时,它会映射 ProjectDto 中的所有值。假设我想通过将以下 JSON 发送到 API 来更新项目名称:
{
"projectId": 10,
"name": "The new name"
}
由于我没有为 ProjectDto 的所有其他属性指定值,因此 AutoMapper 将在我没有提供值的地方映射默认值。
例如,如果 ProjectDto 有几个额外的字段,它们现在将为空:
{
"projectId": 10,
"name": "The new name",
"createdDate": null,
"manager": null
}
..等等
我的映射如下所示:
cfg.CreateMap<ProjecDto, Project>()
.ForAllMembers(opt => opt.Condition(x => x != null));
.. 但 AutoMapper 仍在映射空值。
我查看了this question,但是当我尝试复制他们的解决方案时,我只是得到“ProjectDto 不包含 IsSourceValueNull 的定义”。
Web API 控制器操作(它是通用的,TDto 是一个空标记接口。T 和 TDto 在运行时分别解析为 Project 和 ProjectDto。):
public virtual async Task<IHttpActionResult> Put(string id, [FromBody] TDto model)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var entity = _dataContext.GetRepository<T>().GetById(id);
if (entity == null)
return NotFound();
var entityToUpdate = _mapper.Map<T>(model);
var updatedEntity = _dataContext.GetRepository<T>().Update(entity);
var updatedEntityDto = _mapper.Map<TDto>(updatedEntity);
return Ok(updatedEntityDto);
}
【问题讨论】:
-
您想合并到一个已初始化的对象上并保留未指定的目标值或以某种方式从 api 请求 json 中可选的目标值?小心,你怎么知道 null 意味着清除值或不发送值的意图?
-
不确定我是否理解您的意思,但我只想更新来自客户端的 ProjectDto 中指定的字段
-
嗯。真的吗?正如您在更新的问题中看到的那样,我有一个通用控制器,并且并不真正知道编译时对象上存在哪些属性。
标签: c# asp.net-web-api automapper