【问题标题】:Can't Figure Out How To Use AutoMapper With Post Action In RESTful Api无法弄清楚如何在 RESTful Api 中使用 AutoMapper 和 Post Action
【发布时间】:2021-03-11 16:25:09
【问题描述】:

我有一个简单的 RESTful API,这是我尝试在其中应用 AutoMapper 的后路由处理程序:

    [HttpPost]
    [Route("[action]")]
    public async Task<IActionResult> CreateHotel([FromBody]Hotel hotelCreateDto)
    {
        var hotel = _mapper.Map<Hotel>(hotelCreateDto);

        var createdHotel = await _hotelService.CreateHotel(hotel);

        var hotelReadDto = _mapper.Map<HotelReadDto>(createdHotel);

        return CreatedAtAction("GetHotelById", new { id = hotelReadDto.Id }, hotelReadDto);
    }

所以在请求中我得到了一个hotelCreateDto,它看起来像这样:

 public class HotelCreateDto
{
    [StringLength(50)]
    [Required]
    public string Name { get; set; }

    [StringLength(50)]
    [Required]
    public string City { get; set; }
}

我将其映射到酒店实体:

public class Hotel
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [StringLength(50)]
    [Required]
    public string Name { get; set; }

    [StringLength(50)]
    [Required]
    public string City { get; set; }
}

并在下一行创建一个新的酒店对象。但是,当将hotelReadDto 分配给新的映射对象时,会出现 500 错误:“AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping.

你能在这里发现一个错误吗?我不知道我哪里做错了。

编辑:上面的错误之后还有这个东西:“映射类型: 对象 -> HotelReadDto System.Object -> HotelFinder.DTO.DTOs.HotelReadDto"

Edit2:这是配置服务中的代码:

services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

在 Profile 类中:

public class HotelProfile : Profile
{
    public HotelProfile()
    {
        CreateMap<Hotel, HotelReadDto>();
        CreateMap<HotelCreateDto, Hotel>();
    }
}

【问题讨论】:

  • 看看exception.ToString(),它会告诉你正是出了什么问题。
  • 我在邮递员的回复中没有看到类似的内容。
  • 您的代码缺少一些重要部分(HotelReadDto、_mapper)
  • 您的映射器配置设置是否正确?您是否在调用 CreateMap 时使用 MapperConfiguration 或 Profile? docs.automapper.org/en/stable/Configuration.html
  • 我正在使用带有两个 CreateMap 调用的配置文件。

标签: asp.net asp.net-core asp.net-web-api automapper


【解决方案1】:

在启动时将其添加到您的服务中:

它可重复使用且更清洁

 public void ConfigureServices(IServiceCollection services)
{
            services.AddAutoMapper(Assembly.GetExecutingAssembly());
}

在你的项目中添加这些接口和类

public interface IMapFrom<T>
{
        void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType());
}
using AutoMapper;
using System;
using System.Linq;
using System.Reflection;

    public class MappingProfile : Profile
    {
        public MappingProfile()
        {
            ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly());
        }

        private void ApplyMappingsFromAssembly(Assembly assembly)
        {
                var types = assembly.GetExportedTypes()
                .Where(t => t.GetInterfaces()
                .Any(i =>i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>)))
                .ToList();

            foreach (var type in types)
            {
                var instance = Activator.CreateInstance(type);

                var methodInfo = type.GetMethod("Mapping")
                    ?? type.GetInterface("IMapFrom`1").GetMethod("Mapping");

                methodInfo?.Invoke(instance, new object[] { this });

            }
        }
    }

你的 dto 是这样的(将酒店映射到 HotelDto):

 public class HotelCreateDto : IMapFrom<HotelCreateDto>
    {
        [StringLength(50)]
        [Required]
        public string Name { get; set; }

        [StringLength(50)]
        [Required]
        public string City { get; set; }
        public void Mapping(Profile profile)
        {
            profile.CreateMap<Hotel,HotelCreateDto>();
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    相关资源
    最近更新 更多