2015-06-10 15 views
5

Tôi nhận được lỗi sau và lỗi này chỉ xuất hiện khi nhiều người dùng đang nhấn cùng một nút. Mọi trợ giúp/ý tưởng sẽ thực sự được đánh giá cao:bộ sưu tập lỗi tự động hóa đã được sửa đổi khi nhiều người dùng đang tạo người dùng

System.InvalidOperationException: Bộ sưu tập đã được sửa đổi; liệt kê hoạt động có thể không thực thi. Tạo: Wed, 10 Tháng 6 2015 07:29:06 GMT

AutoMapper.AutoMapperMappingException:

loại Mapping: User -> User ApplicationSecurityManager.Service.User -> ApplicationSecurityManager.Models.User

Destination đường dẫn: Người dùng

Giá trị nguồn: ApplicationSecurityManager.Service.User ---> System.InvalidOperationException: Bộ sưu tập đã được sửa đổi; liệt kê hoạt động có thể không thực thi. tại 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) tại ApplicationSecurityManager.UserManager.LoadUser (String username) tại ApplicationSecurityManager.UserManager.get_AuthenticatedUser() tại ApplicationSecurityManager.UserManager.IsAuthenticated() tại ApplicationSecurityManager.Infrastructure.ApplicationSecurityAttribute. OnAuthorization (AuthorizationContext filterContext) tại System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters (ControllerContext controllerContext, IList 1 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 nhà nước, Int32 timeout) tại System.Web.Mvc.Async.AsyncResultWrapper. Bắt đầu [TRESult] (AsyncCallback gọi lại, Trạng thái đối tượng, BeginInvokeDelegate bắt đầuDelegate, EndInvokeDelegate 1 endDelegate, Object tag, Int32 timeout) at System.Web.Mvc.Async.AsyncResultWrapper.Begin[TResult](AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate 1 endDelegate, Object tag) tại System.Web.Mvc.Controller. <> c__DisplayClass1d.b__17 (AsyncCallback AsyncCallback, Object asyncState) tại 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, EndInvokeDelegate 1 endDelegate, thẻ Object, Int32 timeout) tại System.Web.Mvc.Controller.BeginExecuteCore (AsyncCallback callback , Object nhà nước) tại 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, EndInvokeDelegate 1 endDelegate, thẻ Object, Int32 timeout) tại System.Web.Mvc.Async.AsyncResultWrapper.Begin (AsyncCallback callback, trạng thái đối tượng, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, Object tag) tại System.Web.Mvc.Controller.BeginExecute (RequestContext requestContext, Gọi lại AsyncCallback, Trạng thái đối tượng) tại System.Web.Mvc.MvcHandler. <> c__DisplayClass8.b__2 (AsyncCallback AsyncCallback, Object asyncState) tại 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, EndInvokeDelegate 1 endDelegate, thẻ Object, Int32 timeout) tại System.Web.Mvc.Async.AsyncResultWrapper.Begin (AsyncCallback callback, Object nhà nước, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, thẻ Object) tại System.Web.Mvc.MvcHandler.BeginProcessRequest (HttpContextBase HttpContext, AsyncCallback callback, Object nhà nước) tại System.Web.HttpApplication.CallHandlerExecutionStep.System .Web.HttpApplication.IExecutionStep.Execute() tại System.Web.HttpApplication.ExecuteStep (IExecutionStep bước, Boolean & completedSynchronously)

Đây là constructor nơi mà tôi nghĩ rằng aftermap là vấn đề nhưng khi gỡ lỗi tôi không nhận được lỗi.

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) 

Depenendency tiêm Mapping:

container.RegisterType(Of IUserManager, UserManager)(New PerThreadLifetimeManager(), 
    New InjectionConstructor(
     ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.Environment.ToString()), 
     ConfigurationManager.AppSettings(Common.Enums.AppSettingKeys.ApplicationCode.ToString())) 
    ) 

Trong saveUserResponse, lỗi là nhận được ném.

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 

Trả lời

1

này được gây ra khi nhiều người dùng chỉnh sửa bộ sưu tập user.Groups cùng trong phương pháp AfterMap() của bản đồ của bạn. Để tránh điều này, hãy khóa mã đang xử lý bộ sưu tập. Ví dụ:

'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) 
+0

tôi đã thực hiện bước này nhưng hơi khác một chút với những gì bạn nói: synclock _mylock Mapper.CreateMap (Tất Service.User, Models.User)() _ .ForMember (Function (dest Như Models.User) dest.ENumber, Sub (tùy chọn) opt.MapFrom (Function (src Như Service.User) src.INumber)) _ .AfterMap (Sub (src Như Service.User, dest Như Models.User) ..code End Sub) endsynclock. vì vậy tôi đặt toàn bộ điều trong đồng bộ thay vì chỉ là mã nhóm. bạn có nghĩ đó là nơi mà vấn đề không? – Baahubali

+1

Hai điều. Hãy nhớ rằng phương pháp AfterMap() không được gọi khi bạn gọi CreateMap(), nhưng sau khi bạn gọi Mapper.Map() và nó gọi các bản đồ mà bạn đã cấu hình. Vì vậy, SyncLock sẽ không hiệu quả theo cách của bạn. Thứ hai, bạn nên luôn khóa ít mã nhất có thể. Đây là một bộ sưu tập trên đối tượng người dùng được phàn nàn trong AfterMap, theo stack trace - mà điểm đến .Groups.Do đó, chỉ khóa chế biến xung quanh bộ sưu tập đó. –

+0

Cảm ơn bạn đã giải thích điều đó. – Baahubali

1

Đây là lỗi khá phổ biến khi sửa đổi bộ sưu tập trong khi lặp lại bộ sưu tập đó. Có thể bạn đang để lại một cái gì đó ở đây chúng ta không thể nhìn thấy? Dù sao trong mã mà bạn đã cung cấp không có bất kỳ kịch bản như vậy từ những gì tôi có thể nhìn thấy. Điều này có nghĩa rằng bạn có thể đang gọi điều này trong môi trường đa luồng và bộ sưu tập đang được sửa đổi trong một số chủ đề khác.

Bạn có thể thử gì?

Nhìn vào khóa enumeration của bạn để chỉ có thể truy cập một chuỗi tại một thời điểm. Có thể nó đang được truy cập nhiều lần khi người dùng nhấp vào nút.

Dưới đây là một liên kết tốt để giúp bạn ra ngoài: http://weblogs.asp.net/leftslipper/mvc-locking-the-routecollection

+0

tôi nghĩ vì các chức năng Automapper.CreateMap và AfterMap được gọi trong hàm tạo của lớp. nếu một số người dùng đang cố lưu đối tượng bằng cách gọi hàm tạo như được liệt kê ở trên và một số người dùng khác tạo đối tượng mới sẽ gọi cho Automapper để sửa đổi bộ sưu tập bằng cách gọi hàm Aftermap sẽ ném bộ sưu tập đã bị sửa đổi lỗi? tôi thậm chí đã thử đặt mã trong đồng bộ nhưng lỗi không thay đổi. tôi đã suy nghĩ về refactoring mã nhưng muốn hoàn toàn hiểu như thế nào chức năng Aftermap hoạt động. – Baahubali

+0

@ user1490835 'Aftermap' chỉ chạy một lần cho mỗi ánh xạ. Nếu bạn chỉ muốn chạy nó một lần, bạn nên đính kèm nó vào một cấu hình ánh xạ List to List và không phải là một mục cấu hình mục; điều này chắc chắn sẽ ném một 'bộ sưu tập đã được sửa đổi lỗi' ... – Codexer

+0

xin lỗi những gì bạn có ý nghĩa của danh sách để lập bản đồ danh sách và không phải là một mục cấu hình mục? – Baahubali

Các vấn đề liên quan