ASP.NET Core MVC中如何将ViewResult.Model转换为实体模型?
问题分析与解决方案
嘿,我帮你捋捋这个问题哈!你在测试里把result.Model转成Post得到null,核心原因是控制器返回的模型类型和你要转的类型不匹配,再加上AutoMapper的配置可能没覆盖反向映射,具体来说:
1. 先搞清楚控制器返回的是什么
你的EditPost方法里,是把查询到的Post对象通过AutoMapper映射成了SavePostViewModel,然后返回给视图的。所以测试里result.Model的实际类型是SavePostViewModel,不是Post!你直接强制转成Post,因为类型完全不一样,肯定会得到null。
2. 解决步骤:
第一步:给AutoMapper加反向映射
如果需要把SavePostViewModel转回Post,你得让AutoMapper知道怎么转。可以直接在原配置里加ReverseMap(),它会自动生成反向的映射规则:
var mapperConfig = new MapperConfiguration(x => x.CreateMap<Post, SavePostViewModel>().ReverseMap());
要是你有自定义的映射规则(比如字段名不一样),也可以显式写反向的Map:
var mapperConfig = new MapperConfiguration(x => { x.CreateMap<Post, SavePostViewModel>(); // 自定义反向映射规则,比如忽略某些不需要的字段 x.CreateMap<SavePostViewModel, Post>() .ForMember(dest => dest.PostCategories, opt => opt.Ignore()); });
第二步:在测试里用AutoMapper做转换
测试里不能直接强转,得先拿到SavePostViewModel,再用AutoMapper转成Post:
// 先拿到控制器返回的ViewModel var viewResult = await controller.EditPost(id) as ViewResult; var savePostViewModel = viewResult.Model as SavePostViewModel; // 初始化和控制器一致的AutoMapper配置 var mapperConfig = new MapperConfiguration(x => x.CreateMap<Post, SavePostViewModel>().ReverseMap()); var mapper = mapperConfig.CreateMapper(); // 现在把ViewModel转成Post Post post = mapper.Map<SavePostViewModel, Post>(savePostViewModel);
第三步:优化建议——抽离AutoMapper配置
为了避免控制器和测试里重复写配置,建议把映射规则抽成一个单独的Profile类,这样两边用同一个配置,不容易出错:
public class BlogMappingProfile : Profile { public BlogMappingProfile() { CreateMap<Post, SavePostViewModel>().ReverseMap(); // 其他映射规则也可以放在这里统一管理 } }
然后控制器和测试里都用这个Profile:
var mapperConfig = new MapperConfiguration(cfg => cfg.AddProfile<BlogMappingProfile>());
3. 额外排查点
如果还是得到null,你得检查这两个地方:
- 控制器里查询的
post是不是null?比如数据库里没有对应id的Post,那映射出来的SavePostViewModel也会是null,result.Model自然就是null了。 - 检查
Post和SavePostViewModel的字段是否匹配?AutoMapper默认只会映射同名同类型的字段,如果字段名不一样,得手动配置映射规则,比如:
CreateMap<Post, SavePostViewModel>() .ForMember(dest => dest.CategoryList, opt => opt.MapFrom(src => src.PostCategories));
内容的提问来源于stack exchange,提问作者Tanjir
相关产品推荐
相关产品推荐

