OrderService is always NULL in production but not in Dev. environment

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
3 years ago
Dear NopCommerce Community,

I have an odd situation. I just created a payment plugin (Mollie) which is working fine, although in local environment.

I have a callback method in the same controller as the configure methods. The callback is being called by the payment provider after payment. This is happens successfully. After this I call the _OrderService to retrieve the order by ordernumber, also this happens successfully in localhost BUT not in PRODUCTION. There I get NullReferenceException.

Here is my code: (the important part)

[HttpPost]
        public async Task<IActionResult> MollieWebHook(string id)
        {
            _logger.Information("ID = " + id);

            OrderResponse retrieveOrder = await _mollieOrderClient.GetOrderAsync(id);
            _logger.Information(retrieveOrder.OrderNumber);

            IOrderService orderService = EngineContext.Current.Resolve<IOrderService>();
            var order = orderService.GetOrderById(Convert.ToInt32(retrieveOrder.OrderNumber));

            order.PaymentStatus = MolliePaymentStatusToNopCommercePaymentStatus(retrieveOrder.Status);

            return Ok(200);
        }


orderService is null. Also when I use DI in the CTOR

Please help, I have no idea what could cause this ONLY in production?
3 years ago
RE: "orderService is null"
Check the System Log to see if Resolve had any errors
3 years ago
New York thank you for your answer.

No Resolve does not trow an error. Not in system log.

I do have an Loglevel: Error of type: Object reference not set to an instance of an object.

System.NullReferenceException: Object reference not set to an instance of an object.
   at Nop.Plugin.Payments.MolliePayments.Controllers.PaymentMolliePaymentsController.MollieWebHook(String id)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)

And so on
3 years ago
In my Mollie Payment Plugin I set the webhookURL as

string webhookUrl = _webHelper.GetStoreLocation() + "mollie/webhook/" + order.Id.ToString();

then have have a route to

[IgnoreAntiforgeryToken]
public virtual IActionResult MollieWebhook(int? orderId, string id)
{
......
            if (orderId.HasValue)
            {
                //Load order by identifier (if provided)
                order = _orderService.GetOrderById(orderId.Value);
            }
......
}
3 years ago
It's being disposed before the GetOrderAsync await returns, which probably happens quickly enough locally but takes too long in production.  

It's not ideal, but you can force GetOrderAsync to run synchronously with a .Wait():
https://www.nopcommerce.com/en/boards/topic/82302/call-async-method-from-nopcommerce-service-layer

Or another approach to try: https://www.nopcommerce.com/en/boards/topic/55357/long-running-scheduled-tasks#211833
3 years ago
af1racing you are totally right, and I appriciate your answer verry much. But how do I Wait for this specific task since it is not a void.

Task.AwaitAll(); is not the answer.

Do you meby have an example or a tip to work with?

Much appriciated!
3 years ago
I believe it would be something like:


var retrieveOrderTask = Task.Run(() =>(_mollieOrderClient.GetOrderAsync(id));
retrieveOrderTask.Wait();
var retrieveOrder = retrieveOrderTask.Result;


You could also try making the synchronous part of your method into a task, chain them together with ContinueWith(), and then await both tasks:
https://stackoverflow.com/questions/55647455/why-is-dispose-called-before-its-finishes-async-task
3 years ago
Once again thank you for the quick answer.

I got the following code (sharing just to show):


[HttpPost]
        public IActionResult MollieWebHook(string id)
        {
            var retrieveOrderTask = Task.Run(() => (_mollieOrderClient.GetOrderAsync(id)));
            retrieveOrderTask.Wait();
            var result = retrieveOrderTask.Result;

            Order order = _orderService.GetOrderById(Convert.ToInt32(result.OrderNumber));
            order.PaymentStatus = MolliePaymentStatusToNopCommercePaymentStatus(result.Status);

            return Ok(200);
        }


But I still get the 'Object reference not set to an instance of an object.' exception.
3 years ago
try resolving orderservice after the wait:


[HttpPost]
        public IActionResult MollieWebHook(string id)
        {
            var retrieveOrderTask = Task.Run(() => (_mollieOrderClient.GetOrderAsync(id)));
            retrieveOrderTask.Wait();
            var result = retrieveOrderTask.Result;

            var orderService= EngineContext.Current.Resolve<IOrderService>();
            Order order = orderService.GetOrderById(Convert.ToInt32(result.OrderNumber));
            order.PaymentStatus = MolliePaymentStatusToNopCommercePaymentStatus(result.Status);

            return Ok(200);
        }


if that doesn't work, set some break points so we know exactly what is null
3 years ago
Sadly but it dit not work. Also I did a little loging. And the problem is with IOrderService being NULL

First log is information log: ord_023ki...
Second log is the result.OrderNumber: 3255
Then I did a loggin on orderService and got: OrderService Nop.Services.Orders.OrderService

Then I added a Warning log in case orderService == null > The warning is Order object is null

So orderObject is definetly null

Because after that I got a NullReference Error
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.