I would like to suggest remote session via TeamViewer or any other tool. I will show the issue. What do you think?
Hi @maliming
Do you mean the project I currently working on? if yes, unfortunatly I can not But I could create sample project which repoduces this issue. I think it will be also easy for you
Steps
Sure
2021-02-24 13:27:47.941 +00:00 [INF] Route matched with {area = "ProductManagement", controller = "Product", action = "CreateProduct", page = ""}. Executing controller action with signature System.Threading.Tasks.Task`1[LinkSE.ProductManagement.Products.ProductDto] CreateProduct(LinkSE.ProductManagement.Products.ProductCreateDto) on controller LinkSE.ProductManagement.Controllers.Products.ProductController (LinkSE.ProductManagement.HttpApi).
2021-02-24 13:27:47.973 +00:00 [DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:a94ba6dc-a8f8-ae4f-fa5c-39faa9bfec06,n:ProductManagement.Products.Create
2021-02-24 13:27:47.974 +00:00 [DBG] Found in the cache: pn:U,pk:a94ba6dc-a8f8-ae4f-fa5c-39faa9bfec06,n:ProductManagement.Products.Create
2021-02-24 13:27:47.974 +00:00 [DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:ProductManagement.Products.Create
2021-02-24 13:27:47.974 +00:00 [DBG] Found in the cache: pn:R,pk:admin,n:ProductManagement.Products.Create
2021-02-24 13:27:47.974 +00:00 [DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:a94ba6dc-a8f8-ae4f-fa5c-39faa9bfec06,n:ProductManagement.Products
2021-02-24 13:27:47.974 +00:00 [DBG] Found in the cache: pn:U,pk:a94ba6dc-a8f8-ae4f-fa5c-39faa9bfec06,n:ProductManagement.Products
2021-02-24 13:27:47.975 +00:00 [DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:ProductManagement.Products
2021-02-24 13:27:47.975 +00:00 [DBG] Found in the cache: pn:R,pk:admin,n:ProductManagement.Products
2021-02-24 13:27:47.975 +00:00 [INF] Authorization was successful.
2021-02-24 13:27:48.023 +00:00 [DBG] Added 0 entity changes to the current audit log
2021-02-24 13:27:48.024 +00:00 [DBG] Added 0 entity changes to the current audit log
2021-02-24 13:27:48.025 +00:00 [INF] Executing ObjectResult, writing value of type 'LinkSE.ProductManagement.Products.ProductDto'.
2021-02-24 13:27:48.025 +00:00 [INF] Executed action LinkSE.ProductManagement.Controllers.Products.ProductController.CreateProduct (LinkSE.ProductManagement.HttpApi) in 84.2536ms
2021-02-24 13:27:48.026 +00:00 [INF] Executed endpoint 'LinkSE.ProductManagement.Controllers.Products.ProductController.CreateProduct (LinkSE.ProductManagement.HttpApi)'
2021-02-24 13:27:48.114 +00:00 [DBG] Added 0 entity changes to the current audit log
2021-02-24 13:27:48.114 +00:00 [DBG] Added 0 entity changes to the current audit log
2021-02-24 13:27:48.180 +00:00 [WRN] An exception occurred, but response has already started!
2021-02-24 13:27:48.180 +00:00 [ERR] An unhandled exception has occurred while executing the request.
LinkSE.Common.Exceptions.AlreadyExistException: Exception of type 'LinkSE.Common.Exceptions.AlreadyExistException' was thrown.
at LinkSE.ProductManagement.Products.EventHandlers.ProductEventHandler.HandleEventAsync(ProductCodeAddingEvent eventData)
at Volo.Abp.EventBus.EventBusBase.TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, Object eventData, List`1 exceptions)
at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(Type eventType, Object eventData)
at Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper.TriggerLocalEvents(List`1 localEvents)
at Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper.TriggerEventsInternalAsync(EntityChangeReport changeReport)
at Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper.TriggerEventsAsync(EntityChangeReport changeReport)
at Volo.Abp.EntityFrameworkCore.AbpDbContext`1.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Volo.Abp.Uow.UnitOfWork.SaveChangesAsync(CancellationToken cancellationToken)
at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken)
at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpJwtTokenMiddlewareExtension.<>c__DisplayClass0_0.<<UseJwtTokenMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
2021-02-24 13:27:48.180 +00:00 [WRN] The response has already started, the error handler will not be executed.
2021-02-24 13:27:48.181 +00:00 [ERR] Connection id "0HM6O5GA1U0OV", Request id "0HM6O5GA1U0OV:00000002": An unhandled exception was thrown by the application.
LinkSE.Common.Exceptions.AlreadyExistException: Exception of type 'LinkSE.Common.Exceptions.AlreadyExistException' was thrown.
at LinkSE.ProductManagement.Products.EventHandlers.ProductEventHandler.HandleEventAsync(ProductCodeAddingEvent eventData)
at Volo.Abp.EventBus.EventBusBase.TriggerHandlerAsync(IEventHandlerFactory asyncHandlerFactory, Type eventType, Object eventData, List`1 exceptions)
at Volo.Abp.EventBus.Local.LocalEventBus.PublishAsync(Type eventType, Object eventData)
at Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper.TriggerLocalEvents(List`1 localEvents)
at Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper.TriggerEventsInternalAsync(EntityChangeReport changeReport)
at Volo.Abp.Domain.Entities.Events.EntityChangeEventHelper.TriggerEventsAsync(EntityChangeReport changeReport)
at Volo.Abp.EntityFrameworkCore.AbpDbContext`1.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Volo.Abp.Uow.UnitOfWork.SaveChangesAsync(CancellationToken cancellationToken)
at Volo.Abp.Uow.UnitOfWork.CompleteAsync(CancellationToken cancellationToken)
at Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Builder.ApplicationBuilderAbpJwtTokenMiddlewareExtension.<>c__DisplayClass0_0.<<UseJwtTokenMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.HandleException(HttpContext context, ExceptionDispatchInfo edi)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass6_1.<<UseMiddlewareInterface>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
2021-02-24 13:27:48.181 +00:00 [INF] Request finished HTTP/1.0 POST https://api.linkse.dev/api/product-management/products application/json 104 - 200 - application/json;+charset=utf-8 254.6321ms
Hi
Actually before removal of http client lib asll wroked, and after removal endpoints work too. Why I need to remove this libs when ABP Commecrcial modules http client libs are referenced by application?
I created several modules using ABP suite. Every module provides API, does not have Web GUI. Also I have Application which generated by ABP Suite. I included my modules to application.
I run application and call endpoint of module. The endpoint returns OK result or ERR_INCOMPLETE_CHUNKED_ENCODING. But in the log I can find BusinessException expection which thrown during endpoint call. Also before this expection there is "An exception occurred, but response has already started
" message.
The expection is thrown in local event handler, which is triggered in by domain entity.
When I run module separatly, using host in module solution, endpoint works well and returns error when exception occurs
Endpoint
[Authorize(ProductManagementPermissions.Products.Create)]
public virtual async Task<ProductDto> CreateProduct(ProductCreateDto input)
{
Product product;
var attributeSet =
await _attributeSetRepository.InsertAsync(new AttributeSet(_guidGenerator.Create()), true);
var imageUri = !string.IsNullOrWhiteSpace(input.ImageUri) ? new Uri(input.ImageUri) : null;
product = new Product(
_guidGenerator.Create(),
_currentTenant.Id,
new ProductTitle(input.Title),
attributeSet,
new ProductCode(input.Code),
imageUri);
await _productRepository.InsertAsync(product);
return ObjectMapper.Map<Product, ProductDto>(product);
}
Product
public class Product : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public Guid? TenantId { get; }
public Guid? GroupId { get; }
public Guid AttributeSetId { get; }
public ProductTitle Title { get; private set; }
public ProductCode Code { get; private set; }
public Uri? ImageUri { get; private set; }
protected Product()
{
}
public Product(
Guid id,
Guid? tenantId,
ProductTitle title,
AttributeSet attributeSet,
ProductCode productCode,
Uri? imageUri = null)
: base(id)
{
TenantId = tenantId;
AttributeSetId = attributeSet.Id;
ImageUri = imageUri;
SetCode(productCode);
SetTitle(title);
}
internal Product(
Guid id,
Guid? tenantId,
Group group,
ProductTitle title,
AttributeSet attributeSet,
ProductCode productCode,
Uri? imageUri = null)
: this(id, tenantId, title, attributeSet, productCode, imageUri)
{
GroupId = group.Id;
}
public StockKeepingUnit CreateSku(Guid id, SkuCode code, SkuTitle title, AttributeSet attributeSet)
{
Check.NotNull(attributeSet.ParentAttributeSetId, nameof(attributeSet.ParentAttributeSetId));
var childHasDifferentParentSet = AttributeSetId != attributeSet.ParentAttributeSetId;
if (childHasDifferentParentSet)
{
throw new AttributeSetNotInheritedFromParentAttributeSetException(
parentSetId: AttributeSetId,
parentSetIdInChild: attributeSet.ParentAttributeSetId.Value);
}
return new StockKeepingUnit(
id,
TenantId,
this,
attributeSet,
title,
code,
ImageUri);
}
public void ChangeTitle(ProductTitle title)
{
SetTitle(title);
}
public void ChangeImageUri(Uri imageUri)
{
Check.NotNull(imageUri, nameof(imageUri));
}
private void SetTitle(ProductTitle title)
{
Check.NotNull(title, nameof(title));
Title = title;
AddLocalEvent(new ProductTitleAddingEvent()
{
Title = title
});
}
private void SetCode(ProductCode productCode)
{
Check.NotNull(productCode, nameof(productCode));
Code = productCode;
AddLocalEvent(new ProductCodeAddingEvent()
{
ProductCode = productCode
});
}
}
Event handler
public class ProductEventHandler :
ILocalEventHandler<ProductTitleAddingEvent>,
ILocalEventHandler<ProductCodeAddingEvent>,
ITransientDependency
{
private readonly ICurrentTenant _currentTenant;
private readonly IProductRepository _productRepository;
public ProductEventHandler(
ICurrentTenant currentTenant,
IProductRepository productRepository)
{
_currentTenant = currentTenant;
_productRepository = productRepository;
}
public async Task HandleEventAsync(ProductTitleAddingEvent eventData)
{
if (await TitleAlreadyExist(eventData.Title))
{
throw new AlreadyExistException(eventData.Title.Value, nameof(Product));
}
}
public async Task HandleEventAsync(ProductCodeAddingEvent eventData)
{
if (await CodeAlreadyExist(eventData.ProductCode))
{
throw new AlreadyExistException(eventData.ProductCode.Value, nameof(Product));
}
}
private async Task<bool> TitleAlreadyExist(ProductTitle title)
{
return await _productRepository.CountAsync(p=>
p.TenantId == _currentTenant.Id && p.Title.Value == title.Value) > 1;
}
private async Task<bool> CodeAlreadyExist(ProductCode productCode)
{
return await _productRepository.CountAsync(p =>
p.TenantId == _currentTenant.Id && p.Code.Value == productCode.Value) > 1;
}
}
Hi @maliming
I have several modules which were inteded to wrok as microservices. These modules communicates with each other using Http API. But now I want put all modules in one application. My question is how to configure application that modules would get injected application services instead of http proxies, which provided by modules in application assembly?
I have modules A and B implemented using ABP module template. Also I have application which created using ABP Application Temaplate I referenced modules A and B in the application accordinly layers. Module A uses API of B (references HttpApi,Client). How can I specify implemention of required by A services, which provided by assembly B?
@liangshiwei Thanks
I agree with you and I would not want to reference domain of another module. I just looking for best way and figure out that my design of modules is just wrong
What is the best way to share entity implementation between multiple modules. Eg I have Attribute entity (holds name and value) with some logic implemented inside I need to use the same implementation in several modules to DRY.
I just look at source code of ABP and found that something similar is done in Framework folder.
Thanks
Yes, thanks you!