-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot access a disposed object. Object name: 'FileBufferingReadStream'. #5
Comments
Hmm, yea, that usually occurs when something messes with the request buffering. We need to allow requests to be replayed as Umbraco Commerce needs to do some processing, but then the payment provider needs to do their processing also. I can't see why the If you are introducing your own Middlware or enabling buffering yourself, I'd be more inclined to test around this and seeing if disabling those resolves this. |
Hmm, thanks for the link https://github.com/aspnet/Mvc/blob/release/2.2/src/Microsoft.AspNetCore.Mvc.WebApiCompatShim/HttpRequestMessage/HttpRequestMessageFeature.cs, it is interesting. I will check all my middlewares one more time, but it seems them is not the issue. |
@mattbrailsford This issue was not caused by The main reason here is that PayPal disposing After that code continue executing from line Then if an exception occurred somewhere from line
This exception throw hides the original exception, so I cant find out what exactly happened inside the Callback method. You can reproduce this behaviour, just use PayPal payment provider and throw any exception inside The simple way to reproduce the issue:
public class MyController : System.Web.Http.ApiController // Microsoft.AspNetCore.Mvc.WebApiCompatShim Version=2.2.0.0
{
public async Task Index()
{
Context.Request.EnableBuffering(); // it is important
var request = Context.Request;
if(request.Body.CanSeek)
{
request.Body.Position = 0L;
}
var stream = new StreamContent(request.Body); // NOTE: creating new stream from request body
using(var s = await stream.ReadAsStreamAsync().ConfigureAwait(false))
{
if(s.CanSeek)
{
s.Seek(0, SeekOrigin.Begin);
}
using(var reader = new StreamReader(s))
{
var json = await reader.ReadToEndAsync().ConfigureAwait(false);
Console.WriteLine(json);
}
} // here request body disposed
try
{
var uri = Request.RequestUri.ToString(); // and now we trying to get disposed request
Console.WriteLine(uri);
}
catch(Exception e)
{
throw e;
}
}
}
Possible resolution: please add logic to check I think I should create new issue for PayPal payment provider with reference to this issue. Thanks for support) |
Issue with exception |
Hey @PeterKvayt Really great investigation work so thank you so much for digging in and pinpointing the issue. I think I should be able to transfer this issue over to the PayPal provider repo so I'll try and do so that all the info is kept. |
@PeterKvayt i've just pushed a Would you be in a position to give it a test and see if it sheds any further light on the real underlying issue? See info here for how to use a nightly feed https://docs.umbraco.com/umbraco-cms/fundamentals/setup/install/installing-nightly-builds |
I am glad to hear that you have been pushed I will notice you about my local investigation results as soon as possible. Btw what else was changed in Thanks for support |
Hi @PeterKvayt yea, this is the only thing in there at the moment. As I say, i don't think this is going to be the final solution, just I'm hoping this lets us skip the second issue you highlighted and then hopefully lets us see what the realy issue is (ie, what throws the first exception). Fingers crossed it's a different error we can resolve more easily 😁 |
Hi @mattbrailsford ! I have just reproduced error on my local environment with syntetic exception to see can I find the original exception in logs. I could find it, great😁. The following step is to deliver your fixed version I will keep you updated. |
@PeterKvayt fantastic. Fingers crossed we can get there 🤞 |
Ooh, excellent that we are seeing the right exception now. Do you have code in your solution using entity framework? Umbraco Commerce doesn’t but I know CMS have started to in areas. At least is narrowed down to an area to look in to. I appreciate the update. Fingers crossed we’re getting closer to a resolution. 🤞🏻 |
I was able to reproduce this exception locally, It was caused by my code. I have two handlers for Order Finalized Notification which processed actions in parallel with one dbcontext instance. My fix not on our testing stage yet, but I think it was the main exception which cause current issue. So let's summarize:
Anyway thanks a lot for fast response and support! I will write about results after my code deployed on our testing stage. |
Are there any plans to release new version of |
Sorry, forgot to reply but 10.0.12 is out now 👍🏻 |
As I can see fix from |
Describe the bug
When I tried to complete order, the following exception occurred: "System.ObjectDisposedException: Cannot access a disposed object. Object name: 'FileBufferingReadStream'"
Steps To Reproduce
Steps to reproduce the behavior:
Expected behavior
There is no exception "System.ObjectDisposedException: Cannot access a disposed object. Object name: 'FileBufferingReadStream'"
Additional context
There is a stack trace of exception:
Umbraco Commerce version:
v10.0.10
Umbraco.Commerce.PaymentProviders.PayPal:
v10.0.0
Possible fix
It may caused by enabled request buffering, but umbraco commerce already has
Umbraco.Commerce.Cms.Web.Mvc.UmbracoCommerceRequestBufferingMiddleware
which enable it.Another possible reason is storing HttpContext in field of
Umbraco.Commerce.Web.Mvc.HttpRequestMessageFeature
class.Even though scoped services in ASP.NET Core have a lifetime that matches the request, there are still compelling reasons to avoid storing HttpContext directly in fields within those services. Here's why:
The HttpContext and its features like ISession are designed to be accessed per-request and are tied to the specific HTTP request lifecycle. Storing them in a field and accessing them later can lead to an inconsistent state if the service instance is reused in a different context within the same request or if the session state changes.
ASP.NET Core manages the disposal of HttpContext and its components. If you store these components in fields, you risk accessing disposed objects, especially if any asynchronous operations are involved that might delay the service method execution.
HttpContext and its features are not thread-safe. Storing them in a field increases the risk of concurrent access issues. Each access to HttpContext should be fresh and scoped to the current request processing pipeline to ensure thread safety.
ASP.NET Core's Dependency Injection (DI) pattern is designed for services to access their dependencies directly. This means services should use IHttpContextAccessor to access HttpContext or ISession on-demand. This ensures that you always get the current, correct instance without risking lifecycle or concurrency issues.
I think storing HttpContext in field of
Umbraco.Commerce.Web.Mvc.HttpRequestMessageFeature
leading this issue and insted storing HttpContext in field we should useIHttpContextAccessor
.Thanks for help)
The text was updated successfully, but these errors were encountered: