AutoMapper 实体到 Dto 转换:映射类型错误
AutoMapper Entity to Dto Conversion: Mapping Type Error
我的实体中有不应该暴露给外部的数据。所以我想通过将实体映射到 dto 来导出实体。我收到的数据类型为 IList<Article>
。我需要将其转换为 IList<ArticleBasicDto>
但是当我尝试这样做时出现错误。
我尝试用这种方式导出IList<ArticleBasicDto>
作为目标,但是失败了。刚刚学习,没有达到效果,怎么办?
我这样做的原因是文章中关于用户实体的信息太多了。另外,JSON输出中的Article Object中有一个Category字段,属于该Category的文章会在该字段中再次列出。我正在尝试使用 Dto 来摆脱这些不必要的字段。
错误信息
An unhandled exception occurred while processing the request.
AutoMapperMappingException: Missing type map configuration or
unsupported mapping.
Mapping types: Article -> ArticleBasicDto
Blog.Entities.Concrete.Article -> Blog.Entities.Dtos.ArticleBasicDto
lambda_method178(Closure , Article , ArticleBasicDto ,
ResolutionContext )
AutoMapperMappingException: Error mapping types.
Mapping types: IList1 -> IList
1
System.Collections.Generic.IList1[[Blog.Entities.Concrete.Article, Blog.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.IList
1[[Blog.Entities.Dtos.ArticleBasicDto,
Blog.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
lambda_method177(Closure , IList , IList ,
ResolutionContext )
映射器简介
namespace Blog.Business.AutoMapper.Profiles
{
public class ArticleProfile : Profile
{
public ArticleProfile()
{
CreateMap<Article, ArticleBasicDto>().ForMember(dest => dest.Category, opt => opt.MapFrom(x => x.Category)).ForMember(dest => dest.User,
opt => opt.MapFrom(x => x.User));
}
}
}
Dtos
namespace Blog.Entities.Dtos
{
public class ArticleBasicDto
{
public string Title { get; set; }
public string Content { get; set; }
public string Thumbnail { get; set; }
public DateTime Date { get; set; }
public int ViewsCount { get; set; } = 0;
public int CommentCount { get; set; } = 0;
public UserBasicDto User { get; set; }
public CategoryBasicDto Category { get; set; }
}
}
namespace Blog.Entities.Dtos
{
public class CategoryBasicDto
{
public string Name { get; set; }
public string Description { get; set; }
public string Slug { get; set; }
}
}
namespace Blog.Entities.Dtos
{
public class UserBasicDto
{
public string Email { get; set; }
public string Username { get; set; }
public string Picture { get; set; }
}
}
经理GetAllBasic
方法
public async Task<IDataResult<ArticleBasicListDto>> GetAllBasic()
{
var results = await _unitOfWork.Articles.GetAllAsync();
var mapping = _mapper.Map<IList<ArticleBasicDto>>(results);
return new DataResult<ArticleBasicListDto>(ResultStatus.Success, new ArticleBasicListDto()
{
Articles = mapping,
});
}
MVC 层 - Startup.cs
namespace Blog.MVC
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddRazorRuntimeCompilation().AddNewtonsoftJson(opt => opt.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddAutoMapper(typeof(Startup));
services.LoadMyServices();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePages();
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute(
name: "Admin",
areaName: "Admin",
pattern: "Admin/{controller=Home}/{action=Index}/{id?}"
);
endpoints.MapDefaultControllerRoute();
endpoints.MapControllers();
});
}
}
}
要解决此问题,您必须将 startup
class 替换为 ArticleProfile
,如下所示 services.AddAutoMapper(typeof(ArticleProfile ));
它将解决您的问题。
您需要为用户和类别定义映射
CreateMap<User,CategoryBasicDto>();
CreateMap<Category,CategoryBasicDto>();
我的实体中有不应该暴露给外部的数据。所以我想通过将实体映射到 dto 来导出实体。我收到的数据类型为 IList<Article>
。我需要将其转换为 IList<ArticleBasicDto>
但是当我尝试这样做时出现错误。
我尝试用这种方式导出IList<ArticleBasicDto>
作为目标,但是失败了。刚刚学习,没有达到效果,怎么办?
我这样做的原因是文章中关于用户实体的信息太多了。另外,JSON输出中的Article Object中有一个Category字段,属于该Category的文章会在该字段中再次列出。我正在尝试使用 Dto 来摆脱这些不必要的字段。
错误信息
An unhandled exception occurred while processing the request. AutoMapperMappingException: Missing type map configuration or unsupported mapping.
Mapping types: Article -> ArticleBasicDto Blog.Entities.Concrete.Article -> Blog.Entities.Dtos.ArticleBasicDto lambda_method178(Closure , Article , ArticleBasicDto , ResolutionContext )
AutoMapperMappingException: Error mapping types.
Mapping types: IList
1 -> IList
1 System.Collections.Generic.IList1[[Blog.Entities.Concrete.Article, Blog.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> System.Collections.Generic.IList
1[[Blog.Entities.Dtos.ArticleBasicDto, Blog.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] lambda_method177(Closure , IList , IList , ResolutionContext )
映射器简介
namespace Blog.Business.AutoMapper.Profiles
{
public class ArticleProfile : Profile
{
public ArticleProfile()
{
CreateMap<Article, ArticleBasicDto>().ForMember(dest => dest.Category, opt => opt.MapFrom(x => x.Category)).ForMember(dest => dest.User,
opt => opt.MapFrom(x => x.User));
}
}
}
Dtos
namespace Blog.Entities.Dtos
{
public class ArticleBasicDto
{
public string Title { get; set; }
public string Content { get; set; }
public string Thumbnail { get; set; }
public DateTime Date { get; set; }
public int ViewsCount { get; set; } = 0;
public int CommentCount { get; set; } = 0;
public UserBasicDto User { get; set; }
public CategoryBasicDto Category { get; set; }
}
}
namespace Blog.Entities.Dtos
{
public class CategoryBasicDto
{
public string Name { get; set; }
public string Description { get; set; }
public string Slug { get; set; }
}
}
namespace Blog.Entities.Dtos
{
public class UserBasicDto
{
public string Email { get; set; }
public string Username { get; set; }
public string Picture { get; set; }
}
}
经理GetAllBasic
方法
public async Task<IDataResult<ArticleBasicListDto>> GetAllBasic()
{
var results = await _unitOfWork.Articles.GetAllAsync();
var mapping = _mapper.Map<IList<ArticleBasicDto>>(results);
return new DataResult<ArticleBasicListDto>(ResultStatus.Success, new ArticleBasicListDto()
{
Articles = mapping,
});
}
MVC 层 - Startup.cs
namespace Blog.MVC
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddRazorRuntimeCompilation().AddNewtonsoftJson(opt => opt.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddAutoMapper(typeof(Startup));
services.LoadMyServices();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseStatusCodePages();
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute(
name: "Admin",
areaName: "Admin",
pattern: "Admin/{controller=Home}/{action=Index}/{id?}"
);
endpoints.MapDefaultControllerRoute();
endpoints.MapControllers();
});
}
}
}
要解决此问题,您必须将 startup
class 替换为 ArticleProfile
,如下所示 services.AddAutoMapper(typeof(ArticleProfile ));
它将解决您的问题。
您需要为用户和类别定义映射
CreateMap<User,CategoryBasicDto>();
CreateMap<Category,CategoryBasicDto>();