Asp.net web api 在本地定义映射时,自动映射会随机失败

Asp.net web api 在本地定义映射时,自动映射会随机失败,asp.net-web-api,automapper,Asp.net Web Api,Automapper,我们正在方法定义中为我的asp.net MVC/Web API项目配置automapper,如下所示 public HttpResponseMessage GetDetails(int assignmentId) { var valuation = _valuationRepository.GetOneById(assignmentId); Mapper.CreateMap<UserLicenses, UserLicenseResponseModel>()

我们正在方法定义中为我的asp.net MVC/Web API项目配置automapper,如下所示

public HttpResponseMessage GetDetails(int assignmentId)
{     
    var valuation = _valuationRepository.GetOneById(assignmentId);

    Mapper.CreateMap<UserLicenses, UserLicenseResponseModel>()
    .ForMember(dest => dest.State, opt => opt.MapFrom(src => src.States.StateCode))
    .ForMember(dest => dest.UserId, opt => opt.MapFrom(src => src.UserId))
    .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => (src.UserProfile != null) ? (src.UserProfile.FirstName + ' ' + src.UserProfile.LastName) : " "));

    Mapper.CreateMap<AdditionalExpenses, AdditionalExpensesResponseModel>();
    Mapper.CreateMap<ValuationAssignment, ValuationAssignmentResponseModel>();

    var model = Mapper.Map<ValuationAssignmentResponseModel>(valuationAssignment);    
    return Request.CreateResponse(HttpStatusCode.OK, new  { Assignment = model });
}
public HttpResponseMessage GetDetails(int-assignmentId)
{     
var valuation=\u valuationRepository.GetOneById(assignmentId);
Mapper.CreateMap()
.FormMember(dest=>dest.State,opt=>opt.MapFrom(src=>src.States.StateCode))
.ForMember(dest=>dest.UserId,opt=>opt.MapFrom(src=>src.UserId))
.ForMember(dest=>dest.FullName,opt=>opt.MapFrom(src=>(src.UserProfile!=null)?(src.UserProfile.FirstName+“”+src.UserProfile.LastName):“”);
CreateMap();
CreateMap();
var模型=Mapper.Map(估价分配);
return Request.CreateResponse(HttpStatusCode.OK,new{Assignment=model});
}
我们注意到api不是随机映射值,响应json为映射字段返回空值

当这种情况发生时,我正在回收应用程序池,它似乎工作了一段时间,我们再次遇到这个问题


文档是指将应用程序_Start中的所有映射存储在Global.asax中。然而,我们正在方法定义中设置它们——这就是我们看到这个问题的原因吗

问题在于Web应用程序是线程化的,而Automapper不是完全线程安全的。i、 e.有些方法和类是线程安全的,有些则不是。如果使用静态类
Mapper
,可能会发生这样的情况:当一个线程试图映射对象时,另一个线程试图重新定义映射,这就是为什么会出现这些随机错误

正如Jasen在他的评论中所说的,您自己在问题中也说过,一种解决方案是在执行第一个请求之前,在一个中心位置定义所有映射,只定义一次,通常在
Application\u Start

另一个选项是使用AutoMapper中的非静态类。也就是说,不要使用
Mapper
而是使用其他非静态类。这样,每个线程都有自己的实例,线程安全性不是一个问题。有关此问题和此替代解决方案的更多信息,请参阅此问答:


顺便说一下,从性能的角度来看,最好只定义一次映射并重用它们,而不是一直重新定义它们。最有可能的是
AutoMapper
使用反射,如果是这样,缓存类型和属性信息是非常明智的,以免降低性能。

为什么您需要为每个请求重新创建映射规则,而不是在应用程序启动时一次?谢谢Jasen。如果我将它们放在app_start中,我如何从存储库调用中注入/替换某些字段?我想我的看法是,我们使用AutoMapper一次性配置ModelA到ModelA的映射以供重用。如果我对每个请求都自定义映射项,那么我最好放弃AutoMapper,在存储库或服务中进行手动映射,因为我没有真正重用任何规则。你不能定义多重
UserLicenses
规则吗?UserLicenses到X,UserLicenses到Y,等等。如果这不够可重用,您还可以映射到接口:UserLicenses到IUser或ILicense。。。另外,
Mapper
CreateMap
是静态的,这可能就是为什么您在根据请求重新定义它们时遇到问题的原因。一旦我将映射代码移动到应用程序启动,我就看不到回收应用程序池的必要性。此外,我还实现了配置文件,并一次加载所有配置文件。谢谢