当多个用户创建用户时修改了自动映射器错误集合
automapper error collection was modified when multiple users are creating a user
我收到以下错误,只有当多个用户点击同一个按钮时才会出现此错误。任何 help/ideas 将不胜感激:
System.InvalidOperationException: Collection was modified; enumeration
operation may not execute. Generated: Wed, 10 Jun 2015 07:29:06 GMT
AutoMapper.AutoMapperMappingException:
Mapping types: User -> User ApplicationSecurityManager.Service.User ->
ApplicationSecurityManager.Models.User
Destination path: User
Source value: ApplicationSecurityManager.Service.User --->
System.InvalidOperationException: Collection was modified; enumeration
operation may not execute. at
System.Collections.Generic.List1.Enumerator.MoveNextRare() at
AutoMapper.TypeMap.<get_AfterMap>b__1(Object src, Object dest) at
AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext
context, IMappingEngineRunner mapper) at
AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context,
IMappingEngineRunner mapper) at
AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext
context) --- End of inner exception stack trace --- at
AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext
context) at AutoMapper.MappingEngine.Map[TDestination](Object
source, Action
1 opts) at
ApplicationSecurityManager.UserManager.LoadUser(String username) at
ApplicationSecurityManager.UserManager.get_AuthenticatedUser() at
ApplicationSecurityManager.UserManager.IsAuthenticated() at
ApplicationSecurityManager.Infrastructure.ApplicationSecurityAttribute.OnAuthorization(AuthorizationContext
filterContext) at
System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext
controllerContext, IList1 filters, ActionDescriptor actionDescriptor)
at
System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback
asyncCallback, Object asyncState) at
System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult
1.Begin(AsyncCallback
callback, Object state, Int32 timeout) at
System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback
callback, Object state, BeginInvokeDelegate beginDelegate,
EndInvokeDelegate1 endDelegate, Object tag, Int32 timeout) at
System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback
callback, Object state, BeginInvokeDelegate beginDelegate,
EndInvokeDelegate
1 endDelegate, Object tag) at
System.Web.Mvc.Controller.<>c__DisplayClass1d.b__17(AsyncCallback
asyncCallback, Object asyncState) at
System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback
callback, Object state, Int32 timeout) at
System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback
callback, Object state, BeginInvokeDelegate beginDelegate,
EndInvokeDelegate
1 endDelegate, Object tag, Int32 timeout) at
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback,
Object state) at
System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback
callback, Object state, Int32 timeout) at
System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback
callback, Object state, BeginInvokeDelegate beginDelegate,
EndInvokeDelegate
1 endDelegate, Object tag, Int32 timeout) at
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback,
Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
endDelegate, Object tag) at
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext,
AsyncCallback callback, Object state) at
System.Web.Mvc.MvcHandler.<>c__DisplayClass8.b__2(AsyncCallback
asyncCallback, Object asyncState) at
System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback
callback, Object state, Int32 timeout) at
System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback
callback, Object state, BeginInvokeDelegate beginDelegate,
EndInvokeDelegate
1 endDelegate, Object tag, Int32 timeout) at
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback,
Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
endDelegate, Object tag) at
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase
httpContext, AsyncCallback callback, Object state) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step,
Boolean& completedSynchronously)
这是构造函数,我认为后图是问题所在,但在调试时我没有收到错误。
Public Sub New(environmentCode As String, applicationCode As String)
MyBase.New(environmentCode, applicationCode)
SOBaseUrl = System.Configuration.ConfigurationManager.AppSettings(Enums.AppSettingKeys.SOBaseUrl.ToString())
If Not String.IsNullOrEmpty(SOBaseUrl) Then
SOBaseUrl = SOBaseUrl.TrimEnd("/")
End If
'Setup mapping.
Mapper.CreateMap(Of Service.User, Models.User)() _
.ForMember(Function(dest As Models.User) dest.ENumber, Sub(opt) opt.MapFrom(Function(src As Service.User) src.INumber)) _
.AfterMap(Sub(src As Service.User, dest As Models.User)
dest.Groups = New List(Of String)
Using service = ApplicationSecurityManager.Service.Factory.GetService()
Dim applicationPermissions = service.LoadPermissionsForUser(dest.Username, MyBase.EnvironmentCode)
If (Not applicationPermissions Is Nothing AndAlso applicationPermissions.Any(Function(x) x.Code = MyBase.ApplicationCode)) Then
dest.Groups = applicationPermissions.Single(Function(x) x.Code = MyBase.ApplicationCode).GroupNames.ToList()
End If
End Using
End Sub)
依赖注入映射:
container.RegisterType(Of IUserManager, UserManager)(New PerThreadLifetimeManager(),
New InjectionConstructor(
ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.Environment.ToString()),
ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.ApplicationCode.ToString()))
)
在 saveUserResponse
中,正在抛出错误。
Public Function Create(user As Common.Models.User, approve As Boolean) As SO.Common.Models.User Implements IUserProvider.Save
Dim saveUserResponse = UserManager.SaveUser(Mapper.Map(Of ApplicationSecurityManager.Service.User)(user))
If Not String.IsNullOrEmpty(saveUserResponse.ErrorMessage) Then
'The Security system returned an error.
Throw New Exception("Security Service returned error: " & saveUserResponse.ErrorMessage)
End If
'Return the username.
Return Mapper.Map(Of Common.Models.User)(saveUserResponse.User)
End Function
这是在迭代集合时修改集合的常见错误。有没有可能你在这里遗漏了一些我们看不到的东西?无论如何,在您提供的代码中,据我所知,没有任何此类情况。这意味着您可能在多线程环境中调用它,并且正在其他线程中修改集合。
你能尝试什么?
考虑锁定您的 enumeration
,这样一次只能访问一个线程。当用户单击按钮时,它可能会被多次访问。
这里有一个很好的 link 可以帮助您:http://weblogs.asp.net/leftslipper/mvc-locking-the-routecollection
这是由于多个用户在映射的 AfterMap() 方法中修改同一个 user.Groups 集合造成的。为避免这种情况,请锁定正在处理集合的代码。例如:
'class level object
private object _myLock = New object()
'Setup mapping.
Mapper.CreateMap(Of Service.User, Models.User)() _
.ForMember(Function(dest As Models.User) dest.ENumber, Sub(opt) opt.MapFrom(Function(src As Service.User) src.INumber)) _
.AfterMap(Sub(src As Service.User, dest As Models.User)
SyncLock _myLock
dest.Groups = New List(Of String)
Using service = ApplicationSecurityManager.Service.Factory.GetService()
Dim applicationPermissions = service.LoadPermissionsForUser(dest.Username, MyBase.EnvironmentCode)
If (Not applicationPermissions Is Nothing AndAlso applicationPermissions.Any(Function(x) x.Code = MyBase.ApplicationCode)) Then
dest.Groups = applicationPermissions.Single(Function(x) x.Code = MyBase.ApplicationCode).GroupNames.ToList()
End If
End Using
End SyncLock
End Sub)
我收到以下错误,只有当多个用户点击同一个按钮时才会出现此错误。任何 help/ideas 将不胜感激:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute. Generated: Wed, 10 Jun 2015 07:29:06 GMT
AutoMapper.AutoMapperMappingException:
Mapping types: User -> User ApplicationSecurityManager.Service.User -> ApplicationSecurityManager.Models.User
Destination path: User
Source value: ApplicationSecurityManager.Service.User ---> System.InvalidOperationException: Collection was modified; enumeration operation may not execute. at System.Collections.Generic.List
1.Enumerator.MoveNextRare() at AutoMapper.TypeMap.<get_AfterMap>b__1(Object src, Object dest) at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.Map(ResolutionContext context, IMappingEngineRunner mapper) at AutoMapper.Mappers.TypeMapMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) --- End of inner exception stack trace --- at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) at AutoMapper.MappingEngine.Map[TDestination](Object source, Action
1 opts) at ApplicationSecurityManager.UserManager.LoadUser(String username) at ApplicationSecurityManager.UserManager.get_AuthenticatedUser() at ApplicationSecurityManager.UserManager.IsAuthenticated() at ApplicationSecurityManager.Infrastructure.ApplicationSecurityAttribute.OnAuthorization(AuthorizationContext filterContext) at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<BeginInvokeAction>b__1e(AsyncCallback asyncCallback, Object asyncState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult
1.Begin(AsyncCallback callback, Object state, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate1 endDelegate, Object tag, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate, Object tag) at System.Web.Mvc.Controller.<>c__DisplayClass1d.b__17(AsyncCallback asyncCallback, Object asyncState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate, Object tag, Int32 timeout) at System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate, Object tag, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) at System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.b__2(AsyncCallback asyncCallback, Object asyncState) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate
1 endDelegate, Object tag, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
这是构造函数,我认为后图是问题所在,但在调试时我没有收到错误。
Public Sub New(environmentCode As String, applicationCode As String)
MyBase.New(environmentCode, applicationCode)
SOBaseUrl = System.Configuration.ConfigurationManager.AppSettings(Enums.AppSettingKeys.SOBaseUrl.ToString())
If Not String.IsNullOrEmpty(SOBaseUrl) Then
SOBaseUrl = SOBaseUrl.TrimEnd("/")
End If
'Setup mapping.
Mapper.CreateMap(Of Service.User, Models.User)() _
.ForMember(Function(dest As Models.User) dest.ENumber, Sub(opt) opt.MapFrom(Function(src As Service.User) src.INumber)) _
.AfterMap(Sub(src As Service.User, dest As Models.User)
dest.Groups = New List(Of String)
Using service = ApplicationSecurityManager.Service.Factory.GetService()
Dim applicationPermissions = service.LoadPermissionsForUser(dest.Username, MyBase.EnvironmentCode)
If (Not applicationPermissions Is Nothing AndAlso applicationPermissions.Any(Function(x) x.Code = MyBase.ApplicationCode)) Then
dest.Groups = applicationPermissions.Single(Function(x) x.Code = MyBase.ApplicationCode).GroupNames.ToList()
End If
End Using
End Sub)
依赖注入映射:
container.RegisterType(Of IUserManager, UserManager)(New PerThreadLifetimeManager(),
New InjectionConstructor(
ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.Environment.ToString()),
ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.ApplicationCode.ToString()))
)
在 saveUserResponse
中,正在抛出错误。
Public Function Create(user As Common.Models.User, approve As Boolean) As SO.Common.Models.User Implements IUserProvider.Save
Dim saveUserResponse = UserManager.SaveUser(Mapper.Map(Of ApplicationSecurityManager.Service.User)(user))
If Not String.IsNullOrEmpty(saveUserResponse.ErrorMessage) Then
'The Security system returned an error.
Throw New Exception("Security Service returned error: " & saveUserResponse.ErrorMessage)
End If
'Return the username.
Return Mapper.Map(Of Common.Models.User)(saveUserResponse.User)
End Function
这是在迭代集合时修改集合的常见错误。有没有可能你在这里遗漏了一些我们看不到的东西?无论如何,在您提供的代码中,据我所知,没有任何此类情况。这意味着您可能在多线程环境中调用它,并且正在其他线程中修改集合。
你能尝试什么?
考虑锁定您的 enumeration
,这样一次只能访问一个线程。当用户单击按钮时,它可能会被多次访问。
这里有一个很好的 link 可以帮助您:http://weblogs.asp.net/leftslipper/mvc-locking-the-routecollection
这是由于多个用户在映射的 AfterMap() 方法中修改同一个 user.Groups 集合造成的。为避免这种情况,请锁定正在处理集合的代码。例如:
'class level object
private object _myLock = New object()
'Setup mapping.
Mapper.CreateMap(Of Service.User, Models.User)() _
.ForMember(Function(dest As Models.User) dest.ENumber, Sub(opt) opt.MapFrom(Function(src As Service.User) src.INumber)) _
.AfterMap(Sub(src As Service.User, dest As Models.User)
SyncLock _myLock
dest.Groups = New List(Of String)
Using service = ApplicationSecurityManager.Service.Factory.GetService()
Dim applicationPermissions = service.LoadPermissionsForUser(dest.Username, MyBase.EnvironmentCode)
If (Not applicationPermissions Is Nothing AndAlso applicationPermissions.Any(Function(x) x.Code = MyBase.ApplicationCode)) Then
dest.Groups = applicationPermissions.Single(Function(x) x.Code = MyBase.ApplicationCode).GroupNames.ToList()
End If
End Using
End SyncLock
End Sub)