aspnetboilerplate: Throwing EntityNotFoundException from AppService causes InvalidOperationException
Version Info
- Abp: 4.1.0
- .NET Core: netcoreapp2.1 and netcoreapp2.2 (tested both)
- Microsoft.AspNetCore.Server.Kestrel: 2.2.0
Steps to Reproduce:
- Download the .NET Core Angular SPA sample (Make sure that the “One solution” option is checked)
- Run the Migrations etc
- Call the User’s Get Api with Id >= 2 (/api/services/app/User/Get) <-- The only place where EntityNotFoundException gets thrown from the AppService layer
Expected Result (when called from SwaggerUI)
{
"result": null,
"targetUrl": null,
"success": false,
"error": {
"code": 0,
"message": "There is no entity User with id = 2!",
"details": null,
"validationErrors": null
},
"unAuthorizedRequest": false,
"__abp": true
}
Actual Result (command window logs)
INFO 2019-01-30 09:52:17,439 [14 ] ore.Mvc.Internal.ControllerActionInvoker - Executed action CompanyTest.Project.Users.UserAppService.Get (CompanyTest.Project.Application) in 2457.0942ms
ERROR 2019-01-30 09:52:18,424 [14 ] Microsoft.AspNetCore.Server.Kestrel - Connection id "0HLK6GSE37A0J", Request id "0HLK6GSE37A0J:00000005": An unhandled exception was thrown by the application.
System.InvalidOperationException: StatusCode cannot be set because the response has already started.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAlreadyStartedException(String value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.Microsoft.AspNetCore.Http.Features.IHttpResponseFeature.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Http.Internal.DefaultHttpResponse.set_StatusCode(Int32 value)
at Microsoft.AspNetCore.Builder.Internal.ApplicationBuilder.<>c.<Build>b__16_0(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIIndexMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at CompanyTest.Project.Web.Host.Startup.Startup.<>c.<<Configure>b__4_1>d.MoveNext() in D:\Dev\asp.net core\CompanyTest.Project\4.4.0\src\CompanyTest.Project.Web.Host\Startup\Startup.cs:line 100
Potential Fix Not sure if this is an actual fix or not, but in Startup.cs, only call the next() action in the middle-ware pipeline if the Response hasn’t started yet:
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
{
context.Request.Path = "/index.html";
if (!context.Response.HasStarted) // <--- FIX?
await next();
}
});
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 16 (9 by maintainers)
I understand what you mean, I will try again.