Open Closed

Exception in HttpApi.Host on non AbpController [CSLA.NET] #1870


User avatar
0
Jurjen created
  • ABP Framework version: v4.4.2
  • UI type: Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes (IDserver not seperate)
  • Exception message and stack trace: In download
  • Steps to reproduce the issue: in download PDF

Good afternoon,

We’re experiencing some problems when using CSLA.NET (https://cslanet.com/)with your product (commercial).

In project HttpApi.Host we are using a DataPortalController (api-controller) wich does NOT inherit from AbpController. This controller can be used from various clients to retrieve Csla-businessobjects.

We’ve been prototyping this in the beginning of Q2 using ABP.IO v4.3 and back then it worked fine.

Last week we picked up where we left of in April and for some reason it doesn’t work anymore. We’re getting errors in the HttpApi.Host project (see Error-StackTrace in logs.txt below)

We’ve spent several days chasing this problem and we think there’s some middleware or ‘hook’ into the http pipeline which tries to change something in the response.

We’ve isolated the CSLA.NET in a separate solution, not using ABP.IO, just a regular WebApi Core project in combination with a regular Blazor client and that works fine. We think that there’s something in the ABP http-pipeline causing this. Maybe it’s the ABP-Auditing? (We tried to disable auditing for this controller with [DisableAuditing] attribute but that doesn't seem to make a difference, still throws an exception)

We were wondering if you could help us in locating the problem (and resolving the problem) as you’re far more familiar with how http works in ABP.IO.

Flow:

[BlazorClient] BusinessObject Person

[BlazorClient] Person.Get(23)                 // Get person where Id =23

[BlazorClient] Remote DataPortal is called over http   https://localhost:<port>/DataPortal

[HttpApi]      Call is received, Fetch is called on BusinessObject Person

[HttpApi]      Normally the Fetch will do a DB call but in this example we just fill properties with
               some fixed values.

[HttpApi]      When the response is sent/returned from the DataPortal to the requesting client it
               seems that there is ‘something’ wich interveens and somehow causes a problem.

As you can see in the log (in StepsToReproduce.PDF), the controller-method PostAsync is successful after wich something is done resulting in ‘Added 0 entity changes to the current audit log’ (twice) and the an exception occurs.

As we cannot attach files I've created a weTransfer link : <Removed> This download contains the example code + database backup and StepsToReproduce.PDF If the link has expired, please contact me via info@idas.nl for a new link of I can send the files to you directly.

Please don't hesitate to contact me if you cannot reproduce the problem or if you're having questions.

Kind regards

Jurjen de Groot Idas BV


7 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I will fix this in Abp. You can use code below to fix the problem temporary.

    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var configuration = context.Services.GetConfiguration();
        var hostingEnvironment = context.Services.GetHostingEnvironment();
    
        context.Services.Configure<MvcOptions>(options =>
        {
            options.Filters.ReplaceOne(x => x is ServiceFilterAttribute && x.As<ServiceFilterAttribute>().ServiceType  == typeof(AbpNoContentActionFilter),
                metadata => new ServiceFilterAttribute(typeof(MyNoContentActionFilter)) { Order = 0 });
        });
    }
    
    using System.Net;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc.Abstractions;
    using Microsoft.AspNetCore.Mvc.Filters;
    using Volo.Abp.DependencyInjection;
    
    namespace Volo.Abp.AspNetCore.Mvc.Response
    {
        public class MyNoContentActionFilter : IAsyncActionFilter, ITransientDependency
        {
            public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
            {
                if (!context.ActionDescriptor.IsControllerAction())
                {
                    await next();
                    return;
                }
    
                await next();
    
                if (!context.HttpContext.Response.HasStarted &&
                    context.HttpContext.Response.StatusCode == (int)HttpStatusCode.OK &&
                    context.Result == null)
                {
                    var returnType = context.ActionDescriptor.GetReturnType();
                    if (returnType == typeof(Task) || returnType == typeof(void))
                    {
                        context.HttpContext.Response.StatusCode = (int)HttpStatusCode.NoContent;
                    }
                }
            }
        }
    }
    
  • User Avatar
    0
    Jurjen created

    Goodmorning Maliming,

    Thanks for you quick response :-) I have added the code to the solution.

    The AbpNoContentActionFilter class from your response needs to be MyNoContentActionFilter?

    When running the code I still get the exception.

    When I remove the code from OnActionExecutionAsync(...) which sets the Response.Statuscode, then the exception does not occur.

    Is that correct ?

    public class MyNoContentActionFilter : IAsyncActionFilter, ITransientDependency
    {
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            await next();
        }
    }       
    

    When you correct this in a next release will this be mentioned in the release notes? So we can remove this custom code from our solution ?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I updated the code, Can you copy and retry?

    https://support.abp.io/QA/Questions/1870?_se=bGltaW5nLm1hQHZvbG9zb2Z0LmNvbQ==#answer-a54796dc-1726-c91c-67b4-39ff13281afb

    We will fix this in next patch version. https://github.com/abpframework/abp/pull/10074

  • User Avatar
    0
    Jurjen created

    Hi,

    The code does not work. Looking at the gitbhub link, I see that
    Response.HasStarted has not been added to the 'if' statement.

    if (context.HttpContext.Response.StatusCode == (int)HttpStatusCode.OK && context.HttpContext.Response.HasStarted == false && // <-- this one context.Result == null) {

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you copy the code form https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Response/AbpNoContentActionFilter.cs ?

  • User Avatar
    0
    Jurjen created

    Yes, that works !! :-D Thank you!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    You're welcome.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11