2

我使用的是普通的 ASP.NET,而不是 .NET Core。

目前,映射运行良好,但我将以下初始化代码放在控制器中并在控制器内调用,经过研究,这可能不是一个好主意。

所以试图让它创建一个新的类来初始化,然后从 Global.asax 调用。但我遇到了一个问题 - 'Mapper' 不包含 'Initialize' 的定义。看起来我正在使用旧版本的 AutoMapper 或其他东西。我在 doco 上读到了这个:每个 AppDomain 只应该进行一次配置。这意味着放置配置代码的最佳位置是在应用程序启动中,例如用于 ASP.NET 应用程序的 Global.asax 文件。通常,配置引导程序类在其自己的类中,并且从启动方法调用此引导程序类。引导程序类应该构造一个 MapperConfiguration 对象来配置类型映射。

那么这如何适应我目前的尝试呢?

我的下一个问题是,一旦正确设置,我该如何在控制器中调用它呢?

感谢您的反馈/评论。

谢谢

控制器中的当前配置(可能不是一个好主意 - 但可以工作):

private MapperConfiguration configuration = new MapperConfiguration(cfg => {
     cfg.CreateMap<Activity, ActivityDTO>()
        .ForMember(dst => dst.OwnerId, src => src.MapFrom(ol => ol.User.Id))
        .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()));
});

当前调用上述配置的方法:

var activitiesDTO = await (db.Activities
    .Include(b => b.User)
    .Include(c => c.Category)
    .Where(q => q.UserId == userId)
    .ProjectTo< ActivityDTO>(configuration)
    .AsQueryable()
    .ApplySort(sortfields)
    .Skip((pageNumber - 1) * pageSize).Take(pageSize)).ToListAsync();   

尝试 - 失败:

AutomapperWebProfile.cs:

public class AutomapperWebProfile : AutoMapper.Profile
    {
        public AutomapperWebProfile()
        {
            CreateMap<Activity, ActivityDTO>()
                .ForMember(dst => dst.OwnerId, src => src.MapFrom(ol => ol.User.Id))
                .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));

            CreateMap<ActivityDTO, Activity>()
                .ForMember(dst => dst.UserId, opt => opt.MapFrom(src => HttpContext.Current.User.Identity.GetUserId()));
        }

        public static void Run()
        {
            AutoMapper.Mapper.Initialize(a =>
            {
               a.AddProfile<AutomapperWebProfile>();
            });
        }
    }

全球.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    AutomapperWebProfile.Run();
    GlobalConfiguration.Configuration.Formatters
        .JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    GlobalConfiguration.Configuration.Formatters
        .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);         
}
4

1 回答 1

0

在进一步研究之后,我想出了这种方法,它类似于我之前所做的,但它更适用于任何人:

AutomapperConfig.cs:

public class ClientMappingProfile : Profile
    {
        public ClientMappingProfile()
        {
            CreateMap<Activity, ActivityDTO>()
                .ForMember(dst => dst.OwnerId, src => src.MapFrom(ol => ol.User.Id))
                .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));

            CreateMap<ActivityDTO, Activity>()
                .ForMember(dst => dst.UserId, opt => opt.MapFrom(src => HttpContext.Current.User.Identity.GetUserId()));
        }
    }

    public class AutoMapperConfig
    {
        public MapperConfiguration Configure()
        {
            var config = new MapperConfiguration(cfg =>
            {
                cfg.AddProfile<ClientMappingProfile>();
            });
            return config;
        }
    }

XXXController.cs:

public class ActivitiesController : ApiController
    {
        private ApplicationDbContext db = new ApplicationDbContext();

        ....

[HttpGet]
        [Route("api/v1/Activities/{sortfields=Id}/{pagenumber=1}/{pagesize=10}", Name="GetActivities")]
        [CacheOutput(ClientTimeSpan = 60, ServerTimeSpan = 60)]
        public async Task<IHttpActionResult> GetActivities(string sortfields, int pageNumber, int pageSize)
        {
            var config = new AutoMapperConfig().Configure();

            ...

            var activitiesDTO = await (db.Activities
                                        .Include(b => b.User)
                                        .Include(c => c.Category)
                                        .Where(q => q.UserId == userId)
                                        .ProjectTo< ActivityDTO>(config)
                                        .AsQueryable()
                                        .ApplySort(sortfields)
                                        .Skip((pageNumber - 1) * pageSize).Take(pageSize)).ToListAsync();   

 ....

return Ok(Data)

}

}

我可能会var config = new AutoMapperConfig().Configure();进入暴露给任何方法的私有属性。

有人使用这种方法吗?我看到有些人通过 Global.asax 进行配置,例如我所做的失败尝试(原始问题)。再次不确定这种方法是否也是旧的解决方案。

你的想法?

于 2019-09-22T01:50:21.693 回答