<cite>alper: </cite> Afak if you make a database transaction in a different thread, db context can be disposed whenever the request ends.
Try to make a new scope in the background thread to use the db context there. You're introducing a race condition since the original db context might be disposed before your task runs.
Thank you very much for the quick reply. Yeah, I was thinking of that possible reason so I directly pass UserId and the OrgUnitId to eventBus, and in there I initialize a new UserManager to update/insert records..
EventBus.Trigger(new UserOrganizationUnitsUpdateDto { UserId = user.Id, OrganizationUnitIds = input.GrantedOrganizationUnits });
Would doing that still have the race condition issue?
I'm using MVC 5.* + AngularJS version, and came across a weird issue when trying to use eventbus.
When I try to use EventBus to do insert/update for a batch of UserOrganizationUnit records:
EventBus.Trigger(new UserOrganizationUnitsUpdateDto { UserId = user.Id, OrganizationUnitIds = input.GrantedOrganizationUnits });
It throws me an error:
$exception {"The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: Saving or accepting changes failed because more than one entity of type 'Abp.Authorization.Users.UserOrganizationUnit' have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration."} System.InvalidOperationException
It works properly if I simply use:
updateList.ForEach(x => _userOrganizationUnitRepository.InsertOrUpdateAsync(x));
But updateList.ForEach(x => _userOrganizationUnitRepository.InsertOrUpdateAsync(x)); would take around 1-2 minutes for 9000 records... So I'm still prefer using eventbus to improve user experience.
The Id column in UserOrganizationUnit is already an identity column in database, but it is not decorated with DatabaseGeneratedOption. Is there a way to work around this issue?
I want to force the user to logout. So that he cannot log in back!
Objective: I need to force the user to log out when I mark the user to Inactive in user management (from a different machine). The user immediately should be redirected to log out page expiring his session so he cannot log back in!
How can we do this?
I got it worked now. We are using angular mvc
I used this in UserManager.cs
this.UserValidator = new UserValidator<User, long>(this)
{
AllowOnlyAlphanumericUserNames = false
};
I am trying to create an user with email id <a href="mailto:[email protected]">[email protected]</a> but Abp throws an error saying User name <a href="mailto:[email protected]">[email protected]</a> is invalid, can only contain letters or digits.
How can we allow '-' in the emails ? As now most of the companies uses such kind of email format!
Hi - Swagger is throwing the following error. I already added c.UseFullTypeNameInSchemaIds(); to WebApiModule.cs file. However, that doesn't seem to resolve the issue. Any ideas to help resolve this?
500 : {"message":"An error has occurred.","exceptionMessage":"Conflicting schemaIds: Duplicate schemaIds detected for types and . See the config setting - "UseFullTypeNameInSchemaIds" for a potential workaround","exceptionType":"System.InvalidOperationException","stackTrace":" at Swashbuckle.Swagger.SchemaRegistry.CreateRefSchema(Type type)\r\n at Swashbuckle.Swagger.SchemaRegistry.GetOrRegister(Type type)\r\n at Swashbuckle.Swagger.SwaggerGenerator.CreateOperation(ApiDescription apiDesc, SchemaRegistry schemaRegistry)\r\n at Swashbuckle.Swagger.SwaggerGenerator.CreatePathItem(IEnumerable1 apiDescriptions, SchemaRegistry schemaRegistry)\r\n at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable
1 source, Func2 keySelector, Func
2 elementSelector, IEqualityComparer`1 comparer)\r\n at Swashbuckle.Swagger.SwaggerGenerator.GetSwagger(String rootUrl, String apiVersion)\r\n at Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\r\n at Abp.WebApi.Controllers.ResultWrapperHandler.
<cite>aaron: </cite>
The hub context is different from the context used by abp's signalr hub context so the event is not associated to the event handler at client side.
That's the same as how Abp.Web.SignalR's SignalRRealTimeNotifier gets CommonHub:
private static IHubContext CommonHub { get { return GlobalHost.ConnectionManager.GetHubContext<AbpCommonHub>(); } }
I finally removed the EventBus backplane and directly call the event handler method from front end... now it works as they will definitely share the same hub context. Thank you Aaron.
I found the issue.. I need to stop the hub and restart to allow the event handlers to be registered.
But when I declare a new hub context at the server side, and use it to broadcast the event data. _hubContext = GlobalHost.ConnectionManager.GetHubContext<AbpCommonHub>(); _hubContext.Clients.All.sendEventData(eventData.Entry); The hub context is differentfrom the context used by abp's signalr hub context so the event is not associated to the event handler at client side. <ins>Could you advice if there is a way for me to use the same hub context with abp's signalr?</ins>
For abp's Chat and Notification functions, I saw messges are starting from **hub.server.sendMessage(message), and then in SendMessage method, you just need to use 'Clients.All.getMessage(anotherMessage)' because the hub context is already there and you are always using the same hub context.
[HubName("shoppingCartHub")]
public class ShoppingCartHandler : AbpCommonHub, IEventHandler<EventData>
{
private IHubContext _hubContext;
public ShoppingCartHandler(IOnlineClientManager onlineClientManager, IClientInfoProvider clientInfoProvider) : base(onlineClientManager, clientInfoProvider)
{
_hubContext = GlobalHost.ConnectionManager.GetHubContext<AbpCommonHub>();
}
public void HandleEvent(EventData eventData)
{
_hubContext.Clients.All.sendEventData(eventData.Entry);
}
}
I'm using EventBus.Trigger to pass the message from the ShoppingCartService application service to the shoppingCartHub, and in the HandleEvent method I called SignalR dynamic method sendEventData.
public class ShoppingCartService : MyProjectAppServiceBase, IShoppingCartService{
...
public async Task EditCartData(ShoppingCartInput shoppingCartInput){
...
EventBus.Trigger(new EventData() { ItemId = itemId});
}
}
According to the comment in following page, I changed my client side a little: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1891">https://github.com/aspnetboilerplate/as ... ssues/1891</a>
I've been having this issue too. I think I may have narrowed it down to abp.signalr.js connecting to the server before the client side events have been established. It seems you need to call $.connection.hub.start() after you have set up your events. I'm guessing it is so that it can do some bindings.
If I set abp.signalr.autoConnect = false and then manually call abp.signalr.connect() at the end of my controller, all clients start receiving calls from the server as expected.
Updated Client Side
abp.signalr = abp.signalr || {};
abp.signalr.autoConnect = false;
$.connection.hub.url = abp.signalr.url || '/signalr';
$.connection.hub.logging = true;
var shoppingCartHub= $.connection.shoppingCartHub;
shoppingCartHub.client.sendEventData= onEntryCreatedorUpdated;
abp.signalr.connect();
console.log("abp.signalr after connect", abp.signalr);
It's still not working... One thing I noticed from console.log("abp.signalr after connect", abp.signalr); is shoppingCartHub is not in the Connection List and is in the Proxies list. Here is the snapshot: [attachment=0:2fz49oxu]2018-05-23_22-30-34.jpg[/attachment:2fz49oxu] Is that the reason why the callback function is not reached?