standard net mvc ejemplo c# asp.net-core automapper

c# - mvc - Cómo configurar Automapper en ASP.NET Core



automapper net standard (11)

Soy relativamente nuevo en .NET, y decidí abordar .NET Core en lugar de aprender las "viejas formas". Encontré un artículo detallado sobre cómo configurar AutoMapper para .NET Core aquí , pero ¿hay un tutorial más simple para un novato?


¡Me lo imaginé! Aquí están los detalles:

  1. Agregue el paquete principal AutoMapper a su solución a través de NuGet .
  2. Agregue el paquete de inyección de dependencia de AutoMapper a su solución a través de NuGet .

  3. Cree una nueva clase para un perfil de mapeo. (Hice una clase en el directorio principal de la solución llamada MappingProfile.cs y MappingProfile.cs el siguiente código). UserDto objeto User y UserDto como ejemplo.

    public class MappingProfile : Profile { public MappingProfile() { // Add as many of these lines as you need to map your objects CreateMap<User, UserDto>(); CreateMap<UserDto, User>(); } }

  4. Luego agregue AutoMapperConfiguration en Startup.cs como se muestra a continuación:

    public void ConfigureServices(IServiceCollection services) { // .... Ignore code before this // Auto Mapper Configurations var mappingConfig = new MapperConfiguration(mc => { mc.AddProfile(new MappingProfile()); }); IMapper mapper = mappingConfig.CreateMapper(); services.AddSingleton(mapper); services.AddMvc(); }

  5. Para invocar el objeto mapeado en código, haga algo como lo siguiente:

    public class UserController : Controller { // Create a field to store the mapper object private readonly IMapper _mapper; // Assign the object in the constructor for dependency injection public UserController(IMapper mapper) { _mapper = mapper; } public async Task<IActionResult> Edit(string id) { // Instantiate source object // (Get it from the database or whatever your code calls for) var user = await _context.Users .SingleOrDefaultAsync(u => u.Id == id); // Instantiate the mapped data transfer object // using the mapper you stored in the private field. // The type of the source object is the first type argument // and the type of the destination is the second. // Pass the source object you just instantiated above // as the argument to the _mapper.Map<>() method. var model = _mapper.Map<UserDto>(user); // .... Do whatever you want after that! } }

¡Espero que esto ayude a alguien que comienza de cero con ASP.NET Core! Agradezco cualquier comentario o crítica ya que todavía soy nuevo en el mundo .NET.


En mi Startup.cs (Core 2.2, Automapper 8.1.1)

public class UserProfile : Profile, IProfile { public UserProfile() { CreateMap<User, UserModel>(); CreateMap<UserModel, User>(); } }

En mi proyecto de acceso a datos

public class Mappings { public static void RegisterMappings() { var all = Assembly .GetEntryAssembly() .GetReferencedAssemblies() .Select(Assembly.Load) .SelectMany(x => x.DefinedTypes) .Where(type => typeof(IProfile).GetTypeInfo().IsAssignableFrom(type.AsType())); foreach (var ti in all) { var t = ti.AsType(); if (t.Equals(typeof(IProfile))) { Mapper.Initialize(cfg => { cfg.AddProfiles(t); // Initialise each Profile classe }); } } } }

En mi definición de modelo

Mappings.RegisterMappings();


Estoy usando AutoMapper 6.1.1 y asp.net Core 1.1.2.

En primer lugar, defina las clases de perfil heredadas por Profile Class of Automapper. Creé la interfaz IProfile que está vacía, el propósito es solo encontrar las clases de este tipo.

public class EmployeesController { private readonly IMapper _mapper; public EmployeesController(IMapper mapper){ _mapper = mapper; }

Ahora cree una clase separada, por ejemplo, asignaciones

var customers = await dbContext.Customers.ProjectTo<CustomerDto>(_mapper.ConfigurationProvider).ToListAsync()

Ahora en MVC Core web Project en el archivo Startup.cs, en el constructor, llame a la clase Mapping que inicializará todas las asignaciones en el momento de la carga de la aplicación.

public class MappingProfile : Profile { public MappingProfile() { CreateMap<Source, Dest>().ReverseMap(); } }


La respuesta de theutz aquí es muy buena, solo quiero agregar esto:

Si deja que su perfil de mapeo herede de MapperConfigurationExpression lugar de Profile , simplemente puede agregar una prueba para verificar su configuración de mapeo, que siempre es útil:

public static IServiceCollection AddAutoMapper(this IServiceCollection services) { return services.AddAutoMapper(null, AppDomain.CurrentDomain.GetAssemblies()); }


Lo resolví de esta manera (similar a lo anterior pero siento que es una solución más limpia) para .NET Core 2.2 / Automapper 8.1.1 w / Extensions.DI 6.1.1.

Cree la clase MappingProfile.cs y complete el constructor con Maps (planeo usar una sola clase para contener todas mis asignaciones)

services.AddAutoMapper(new Type[] { typeof(DAL.MapperProfile) });

En Startup.cs, agregue a continuación para agregar a DI (el argumento de ensamblaje es para la clase que contiene sus configuraciones de mapeo, en mi caso, es la clase MappingProfile).

namespace DAL { public class MapperProfile : Profile { // place holder for AddAutoMapper (to bring in the DAL assembly) } }

En Controller, úselo como lo haría con cualquier otro objeto DI

namespace DAL.Models { public class PositionProfile : Profile { public PositionProfile() { CreateMap<Position, PositionDto_v1>(); } } public class Position { ... }


Para ASP.NET Core, si prefiere leer la documentación de origen: https://github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection/blob/master/README.md

De lo contrario, seguir estos 3 pasos funciona:

  1. Simplemente agregue algunas clases de perfil.
  2. Luego agregue a continuación a su clase startup.cs. services.AddAutoMapper(OneOfYourProfileClassNamesHere)

  3. Luego, simplemente inyecte IMapper en sus controladores o donde lo necesite:

//add automapper DI services.AddAutoMapper(typeof(MappingProfile));

Y si quieres usar ProjectTo es ahora simplemente:

[Route("api/[controller]")] [ApiController] public class AnyController : ControllerBase { private readonly IMapper _mapper; public AnyController(IMapper mapper) { _mapper = mapper; } public IActionResult Get(int id) { var entity = repository.Get(id); var dto = _mapper.Map<Dest>(entity); return Ok(dto); } }


Para agregar a lo que Arve Systad mencionó para las pruebas. Si por alguna razón eres como yo y quieres mantener la estructura de herencia proporcionada en la solución deutz, puedes configurar MapperConfiguration de esta manera:

var mappingProfile = new MappingProfile(); var config = new MapperConfiguration(cfg => { cfg.AddProfile(mappingProfile); }); var mapper = new Mapper(config);

Hice esto en NUnit.


Paso para usar AutoMapper con ASP.NET Core.

Paso 1. Instalar AutoMapper.Extensions.Microsoft.DependencyInjection desde el paquete NuGet.

Paso 2. Cree una carpeta en solución para mantener las asignaciones con el nombre "Asignaciones".

Paso 3. Después de agregar la carpeta Mapping, hemos agregado una clase con el nombre " MappingProfile ". Este nombre puede ser único y bueno de entender.

En esta clase, vamos a mantener todas las asignaciones.

Paso 4. Inicializando Mapper en el inicio "ConfigureServices"

En Startup Class, necesitamos inicializar el perfil que hemos creado y también registrar el servicio AutoMapper.

Mapper.Initialize(cfg => cfg.AddProfile<MappingProfile>()); services.AddAutoMapper();

Fragmento de código para mostrar el método ConfigureServices donde necesitamos inicializar y registrar AutoMapper.

public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); // Start Registering and Initializing AutoMapper Mapper.Initialize(cfg => cfg.AddProfile<MappingProfile>()); services.AddAutoMapper(); // End Registering and Initializing AutoMapper services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }}

Paso 5. Obtener salida.

Para obtener el resultado del mapeo, debemos llamar a AutoMapper.Mapper.Map y pasar el Destino y el Origen adecuados.

AutoMapper.Mapper.Map<Destination>(source);

Fragmento de código

[HttpPost] public void Post([FromBody] SchemeMasterViewModel schemeMaster) { if (ModelState.IsValid) { var mappedresult = AutoMapper.Mapper.Map<SchemeMaster>(schemeMaster); } }


Quiero extender las respuestas de @ theutz, es decir, esta línea:

[Fact] public void MappingProfile_VerifyMappings() { var mappingProfile = new MappingProfile(); var config = new MapperConfiguration(mappingProfile); var mapper = new Mapper(config); (mapper as IMapper).ConfigurationProvider.AssertConfigurationIsValid(); }

Hay un error ( probablemente ) en AutoMapper.Extensions.Microsoft.DependencyInjection versión 3.2.0. (Estoy usando .NET Core 2.0)

Esto se aborda en this problema de GitHub. Si sus clases que heredan la clase Perfil de AutoMapper existen fuera del ensamblaje donde está su clase de Inicio, probablemente no se registrarán si su inyección de AutoMapper se ve así:

// services.AddAutoMapper(typeof(Startup)); // <-- newer automapper version uses this signature.

a menos que especifique explícitamente qué ensamblajes buscar en los perfiles de AutoMapper.

Se puede hacer así en su Startup.ConfigureServices:

services.AddAutoMapper();

donde "ensamblados" y "type_in_assemblies" apuntan al ensamblado donde se especifican las clases de perfil en su aplicación. P.ej:

services.AddAutoMapper(<assembies> or <type_in_assemblies>);

Supongo (y pongo énfasis en esta palabra) que debido a la siguiente implementación de sobrecarga sin parámetros (código fuente de GitHub ):

services.AddAutoMapper(typeof(ProfileInOtherAssembly), typeof(ProfileInYetAnotherAssembly));

confiamos en que CLR ya ha ensamblado JIT que contiene perfiles de AutoMapper que pueden ser o no ciertos ya que solo se modifican cuando es necesario (más detalles en this pregunta de ).


servicios.AddAutoMapper (); No funcionó para mí. (Estoy usando Asp.Net Core 2.0)

Después de configurar como a continuación

var config = new AutoMapper.MapperConfiguration(cfg => { cfg.CreateMap<ClientCustomer, Models.Customer>(); });

inicializar el mapeador IMapper mapper = config.CreateMapper ();

y agregue el objeto mapeador a los servicios como servicios singleton. AddSingleton (mapeador);

de esta manera puedo agregar una DI al controlador

private IMapper autoMapper = null; public VerifyController(IMapper mapper) { autoMapper = mapper; }

y he usado lo siguiente en mis métodos de acción

ClientCustomer customerObj = autoMapper.Map<ClientCustomer>(customer);


sobre la respuesta thez, no hay necesidad de especificar el parámetro del mapeador IMapper en el constructor de controladores.

puede usar el Mapper, ya que es un miembro estático en cualquier lugar del código.

public class UserController : Controller { public someMethod() { Mapper.Map<User, UserDto>(user); } }