the*_*utz 219 c# automapper asp.net-core
我是.NET的新手,我决定解决.NET Core而不是学习"老方法".我在这里找到了一篇关于为.NET Core设置AutoMapper的详细文章,但新手有更简单的演练吗?
the*_*utz 489
我想到了!这是详细信息:
通过NuGet将AutoMapper依赖注入包添加到您的解决方案中.
为映射配置文件创建新类.(我在主解决方案目录中创建了一个类,MappingProfile.cs
并添加以下代码.)我将使用一个User
和UserDto
对象作为示例.
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>();
}
}
Run Code Online (Sandbox Code Playgroud)然后在Startup.cs
如下所示添加AutoMapperConfiguration :
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();
}
Run Code Online (Sandbox Code Playgroud)要在代码中调用映射对象,请执行以下操作:
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!
}
}
Run Code Online (Sandbox Code Playgroud)我希望这有助于有人开始使用ASP.NET Core!我欢迎任何反馈或批评,因为我还是.NET世界的新手!
Sai*_*war 55
步骤将AutoMapper与ASP.NET Core一起使用.
步骤1.从NuGet包安装AutoMapper.Extensions.Microsoft.DependencyInjection.
步骤2.在解决方案中创建一个文件夹,以使映射保持名称"Mappings".
步骤3.添加Mapping文件夹后,我们添加了一个名为" MappingProfile " 的类,这个名称可以是任何独特且易于理解的.
在本课程中,我们将维护所有映射.
步骤4.在启动"ConfigureServices"中初始化Mapper
在Startup Class中,我们需要初始化我们创建的Profile以及Register AutoMapper Service.
Mapper.Initialize(cfg => cfg.AddProfile<MappingProfile>());
services.AddAutoMapper();
Run Code Online (Sandbox Code Playgroud)
代码片段显示我们需要初始化和注册AutoMapper的ConfigureServices方法.
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);
}}
Run Code Online (Sandbox Code Playgroud)
步骤5.获取输出.
要获取Mapped结果,我们需要调用AutoMapper.Mapper.Map并传递Proper Destination和Source.
AutoMapper.Mapper.Map<Destination>(source);
Run Code Online (Sandbox Code Playgroud)
CodeSnippet
[HttpPost]
public void Post([FromBody] SchemeMasterViewModel schemeMaster)
{
if (ModelState.IsValid)
{
var mappedresult = AutoMapper.Mapper.Map<SchemeMaster>(schemeMaster);
}
}
Run Code Online (Sandbox Code Playgroud)
Gra*_*Cat 35
我想扩展@theutz的答案 - 即这一行:
// services.AddAutoMapper(typeof(Startup)); // <-- newer automapper version uses this signature.
Run Code Online (Sandbox Code Playgroud)
AutoMapper.Extensions.Microsoft.DependencyInjection版本3.2.0中存在一个错误(可能).(我使用的是.NET Core 2.0)
这是在这个 GitHub问题中解决的.如果您继承AutoMapper的Profile类的类存在于程序集之外的Startup类,那么如果您的AutoMapper注入如下所示,它们可能不会被注册:
services.AddAutoMapper();
Run Code Online (Sandbox Code Playgroud)
除非您明确指定要搜索AutoMapper配置文件的程序集.
它可以在你的Startup.ConfigureServices中这样完成:
services.AddAutoMapper(<assembies> or <type_in_assemblies>);
Run Code Online (Sandbox Code Playgroud)
其中"assemblies"和"type_in_assemblies"指向指定应用程序中的Profile类的程序集.例如:
services.AddAutoMapper(typeof(ProfileInOtherAssembly), typeof(ProfileInYetAnotherAssembly));
Run Code Online (Sandbox Code Playgroud)
我想(并且我强调这个词)是由于实现了无参数overaload(来自GitHub的源代码):
public static IServiceCollection AddAutoMapper(this IServiceCollection services)
{
return services.AddAutoMapper(null, AppDomain.CurrentDomain.GetAssemblies());
}
Run Code Online (Sandbox Code Playgroud)
我们依赖于CLR已经包含了包含AutoMapper配置文件的JITed程序集,这些配置文件可能是或者可能不是真的,因为它们只在需要时被jitted(在这个 StackOverflow问题中更多的deatils ).
Arv*_*tad 27
theutz'这里的答案非常好,我只想补充一点:
如果你让你的映射配置文件继承MapperConfigurationExpression
而不是Profile
,你可以简单地添加一个测试来验证你的映射设置,这总是很方便:
[Fact]
public void MappingProfile_VerifyMappings()
{
var mappingProfile = new MappingProfile();
var config = new MapperConfiguration(mappingProfile);
var mapper = new Mapper(config);
(mapper as IMapper).ConfigurationProvider.AssertConfigurationIsValid();
}
Run Code Online (Sandbox Code Playgroud)
mar*_*tcs 16
在最新版本的 asp.net core 中,您应该使用以下初始化:
services.AddAutoMapper(typeof(YourMappingProfileClass));
Run Code Online (Sandbox Code Playgroud)
Vic*_*Vic 14
我喜欢很多答案,尤其是@saineshwar 的答案。我正在使用 .net Core 3.0 和 AutoMapper 9.0,所以我觉得是时候更新它的答案了。
对我有用的是 Startup.ConfigureServices(...) 以这种方式注册服务:
services.AddAutoMapper(cfg => cfg.AddProfile<MappingProfile>(),
AppDomain.CurrentDomain.GetAssemblies());
Run Code Online (Sandbox Code Playgroud)
我认为@saineshwar 的其余回答保持完美。但如果有人感兴趣,我的控制器代码是:
[HttpGet("{id}")]
public async Task<ActionResult> GetIic(int id)
{
// _context is a DB provider
var Iic = await _context.Find(id).ConfigureAwait(false);
if (Iic == null)
{
return NotFound();
}
var map = _mapper.Map<IicVM>(Iic);
return Ok(map);
}
Run Code Online (Sandbox Code Playgroud)
我的映射类:
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Iic, IicVM>()
.ForMember(dest => dest.DepartmentName, o => o.MapFrom(src => src.Department.Name))
.ForMember(dest => dest.PortfolioTypeName, o => o.MapFrom(src => src.PortfolioType.Name));
//.ReverseMap();
}
}
Run Code Online (Sandbox Code Playgroud)
- - - 编辑 - - -
在阅读了 Lucian Bargaoanu 评论中链接的文档后,我认为最好稍微改变一下这个答案。
无参数services.AddAutoMapper()
(有@saineshwar 答案)不再起作用(至少对我而言)。但是,如果您使用 NuGet 程序集 AutoMapper.Extensions.Microsoft.DependencyInjection,则该框架能够检查所有扩展 AutoMapper.Profile 的类(如我的 MappingProfile)。
因此,在我的情况下,类属于同一个执行程序集,服务注册可以缩短为services.AddAutoMapper(System.Reflection.Assembly.GetExecutingAssembly());
(更优雅的方法可能是使用这种编码的无参数扩展)。
谢谢,卢西安!
小智 13
我通过.NET Core 2.2 / Automapper 8.1.1 w / Extensions.DI 6.1.1的这种方式(类似于上面的方式解决了,但我觉得这是一个更干净的解决方案)。
创建MappingProfile.cs类并使用Maps填充构造函数(我计划使用一个类来保存我的所有映射)
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Source, Dest>().ReverseMap();
}
}
Run Code Online (Sandbox Code Playgroud)
在Startup.cs中,添加以下内容以添加到DI(程序集arg用于保存您的映射配置的类,在我的情况下,它是MappingProfile类)。
//add automapper DI
services.AddAutoMapper(typeof(MappingProfile));
Run Code Online (Sandbox Code Playgroud)
在Controller中,像使用其他任何DI对象一样使用它
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
Bri*_*ice 10
在我的Startup.cs(Core 2.2,Automapper 8.1.1)中
services.AddAutoMapper(new Type[] { typeof(DAL.MapperProfile) });
Run Code Online (Sandbox Code Playgroud)
在我的数据访问项目中
namespace DAL
{
public class MapperProfile : Profile
{
// place holder for AddAutoMapper (to bring in the DAL assembly)
}
}
Run Code Online (Sandbox Code Playgroud)
在我的模型定义中
namespace DAL.Models
{
public class PositionProfile : Profile
{
public PositionProfile()
{
CreateMap<Position, PositionDto_v1>();
}
}
public class Position
{
...
}
Run Code Online (Sandbox Code Playgroud)
对于 AutoMapper 9.0.0:
public static IEnumerable<Type> GetAutoMapperProfilesFromAllAssemblies()
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var aType in assembly.GetTypes())
{
if (aType.IsClass && !aType.IsAbstract && aType.IsSubclassOf(typeof(Profile)))
yield return aType;
}
}
}
Run Code Online (Sandbox Code Playgroud)
映射器配置文件:
public class OrganizationProfile : Profile
{
public OrganizationProfile()
{
CreateMap<Foo, FooDto>();
// Use CreateMap... Etc.. here (Profile methods are the same as configuration methods)
}
}
Run Code Online (Sandbox Code Playgroud)
在您的启动中:
services.AddAutoMapper(GetAutoMapperProfilesFromAllAssemblies()
.ToArray());
Run Code Online (Sandbox Code Playgroud)
在控制器或服务中:注入映射器:
private readonly IMapper _mapper;
Run Code Online (Sandbox Code Playgroud)
用法:
var obj = _mapper.Map<TDest>(sourceObject);
Run Code Online (Sandbox Code Playgroud)
需要安装一个包来设置自动映射器。
dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection
之后 AddAutoMapper 将在服务中可用。
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(typeof(Startup));
}
Run Code Online (Sandbox Code Playgroud)
创建从 Employee 类到 EmployeeDTO 的映射器。
using AutoMapper;
public class AutomapperProfile: Profile
{
public AutomapperProfile()
{
//Source to destination.
CreateMap<Employee,EmployeeDTO>();
}
}
Run Code Online (Sandbox Code Playgroud)
EmployeeController 从 Employee 映射到 EmployeeDTo
using System.Collections.Generic;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
[ApiController()]
public class EmployeeController : ControllerBase
{
private readonly IMapper _mapper;
public EmployeeController(IMapper mapper)
{
_mapper = mapper;
}
[HttpGet]
public IEnumerable<EmployeeDTO> GetEmployees()
{
/*
Assume it to be a service call/database call
it returns a list of employee, and now we will map it to EmployeeDTO
*/
var employees = Employee.SetupEmployee();
var employeeDTO = _mapper.Map<IEnumerable<EmployeeDTO>>(employees);
return employeeDTO;
}
}
Run Code Online (Sandbox Code Playgroud)
Employee.cs 供参考
using System.Collections.Generic;
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public int Salary { get; set; }
public static IEnumerable<Employee> SetupEmployee()
{
return new List<Employee>()
{
new Employee(){EmployeeId = 1, EmployeeName ="First", Salary=10000},
new Employee(){EmployeeId = 2, EmployeeName ="Second", Salary=20000},
new Employee(){EmployeeId = 3, EmployeeName ="Third", Salary=30000},
new Employee(){EmployeeId = 4, EmployeeName ="Fourth", Salary=40000},
new Employee(){EmployeeId = 5, EmployeeName ="Fifth", Salary=50000}
};
}
}
Run Code Online (Sandbox Code Playgroud)
EmployeeDTO.cs 供参考
public class EmployeeDTO
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我使用的是AutoMapper 6.1.1和asp.net Core 1.1.2.
首先,定义Automapper的Profile Class继承的Profile类.我创建了IProfile接口,它是空的,目的只是找到这种类的类.
public class UserProfile : Profile, IProfile
{
public UserProfile()
{
CreateMap<User, UserModel>();
CreateMap<UserModel, User>();
}
}
Run Code Online (Sandbox Code Playgroud)
现在创建一个单独的类,例如Mappings
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
});
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在在Startup.cs文件中的MVC Core web Project中,在构造函数中,调用Mapping类,它将在应用程序加载时初始化所有映射.
Mappings.RegisterMappings();
Run Code Online (Sandbox Code Playgroud)
在 .NET 6 中,您需要将以下内容添加到Program.cs文件中:
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
Run Code Online (Sandbox Code Playgroud)
对于 ASP.NET Core(使用 2.0+ 和 3.0 测试),如果您更喜欢阅读源文档:https : //github.com/AutoMapper/AutoMapper.Extensions.Microsoft.DependencyInjection/blob/master/README.md
否则按照这 4 个步骤工作:
从 nuget 安装 AutoMapper.Extensions.Microsoft.DependancyInjection。
只需添加一些配置文件类。
然后将下面添加到您的 startup.cs 类。
services.AddAutoMapper(OneOfYourProfileClassNamesHere)
然后只需在您的控制器或您需要的任何地方注入 IMapper:
public class EmployeesController {
private readonly IMapper _mapper;
public EmployeesController(IMapper mapper){
_mapper = mapper;
}
Run Code Online (Sandbox Code Playgroud)
如果您想现在简单地使用 ProjectTo:
var customers = await dbContext.Customers.ProjectTo<CustomerDto>(_mapper.ConfigurationProvider).ToListAsync()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
128533 次 |
最近记录: |