Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Paul Crowdy 35 posts 96 karma points
    29 days ago
    Paul Crowdy
    0

    Custom Product Adapter/Product Snapshot

    Hi Matt,

    I have a custom product adapter that checks the product reference and returns the correct snapshot object. This all seems to be working correctly until one of the snapshots is requested from a callback from the payment provider.

    The error I receive is:

    Unable to cast object of type 'HOI.Core.Adapters.HOIContentAccessSnapshop' to type 'Vendr.Web.Adapters.UmbracoProductSnapshot'.", "ExceptionType" => "System.InvalidCastException", "Message" => "An error has occurred.", "StackTrace" => " at Vendr.Web.Services.UmbracoStockService.GetStockSource(String productReference, String productVariantReference) in D:\a\1\s\src\Vendr.Web\Services\UmbracoStockService.cs:line 147\r\n at Vendr.Web.Services.UmbracoStockService.ReduceStock(String productReference, String productVariantReference, Decimal reduceBy) in D:\a\1\s\src\Vendr.Web\Services\UmbracoStockService.cs:line 84\r\n at Vendr.Core.Services.ProductService.ReduceProductStock(String productReference, String productVariantReference, Decimal reduceBy) in D:\a\1\s\src\Vendr.Core\Services\ProductService.cs:line 44\r\n at Vendr.Core.Events.Domain.Handlers.Order.ReduceOrderStockLevels.ReduceOrderLineStockLevelsRecursive(OrderLineReadOnly orderLine, Decimal parentQuantity) in D:\a\1\s\src\Vendr.Core\Events\Domain\Handlers\Order\ReduceOrderStockLevels.cs:line 27\r\n at Vendr.Core.Events.Domain.Handlers.Order.ReduceOrderStockLevels.Handle(OrderFinalized evt) in D:\a\1\s\src\Vendr.Core\Events\Domain\Handlers\Order\ReduceOrderStockLevels.cs:line 19\r\n at Vendr.Core.Events.Domain.DomainEventHandlerBase1.Vendr.Core.Events.IEventHandler.Handle(IEvent evt) in D:\\a\\1\\s\\src\\Vendr.Core\\Events\\Domain\\DomainEventHandlerBase.cs:line 9\r\n at Vendr.Core.Events.InProcEventDispatcher.Dispatch[T](IEnumerable1 handlers, T evt) in D:\a\1\s\src\Vendr.Core\Events\InProcEventDispatcher.cs:line 11\r\n at Vendr.Core.Events.EventBus.Dispatch[T](T evt) in D:\a\1\s\src\Vendr.Core\Events\EventBus.cs:line 41\r\n at Vendr.Core.Models.AggregateBase3.RaiseDomainEvents() in D:\\a\\1\\s\\src\\Vendr.Core\\Models\\AggregateBase.cs:line 98\r\n at Vendr.Core.Services.OrderService.SaveOrder(Order entity) in D:\\a\\1\\s\\src\\Vendr.Core\\Services\\OrderService.cs:line 213\r\n at Vendr.Core.Web.Controllers.VendrPaymentController.Callback(IPaymentProvider paymentProvider, OrderReference orderReference) in D:\\a\\1\\s\\src\\Vendr.Core.Web\\Controllers\\VendrPaymentController.cs:line 231\r\n at Vendr.Core.Web.Controllers.VendrPaymentController.HandleRequestWithOrder(String requestType, String paymentProviderAlias, Guid orderId, String orderNumber, String hash, Func3 handler) in D:\a\1\s\src\Vendr.Core.Web\Controllers\VendrPaymentController.cs:line 270\r\n at Vendr.Core.Web.Controllers.VendrPaymentController.Callback(String vendrPaymentProviderAlias, Guid vendrOrderId, String vendrOrderNumber, String vendrHash) in D:\a\1\s\src\Vendr.Core.Web\Controllers\VendrPaymentController.cs:line 144\r\n at lambdamethod(Closure , Object , Object[] )\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>cDisplayClass62.b2(Object instance, Object[] methodParameters)\r\n at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ApiControllerActionInvoker.d1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Controllers.ActionFilterResult.d5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Web.Http.Filters.AuthorizationFilterAttribute.d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebugger

    I'm not using the stock functionality on any of the products at the moment, and I can't see to find out what is causing this issue on only one of the of the snapshots.

    Any ideas?

    Thanks,

    Paul.

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    28 days ago
    Matt Brailsford
    1

    Hi Paul,

    I believe I fixed this in 1.7.0 which was released last week so upgrading should resolve this.

    Be sure to check the changelog for details on anything else that might have changed https://vendr.net/docs/core/changelog/

    Matt

  • Paul Crowdy 35 posts 96 karma points
    28 days ago
    Paul Crowdy
    0

    Ah that would explain it - Thanks as always!

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    Hi Matt,

    Can you explain a little bit about how the caching now works since the upgrade from 1.6 -> 1.7 please?

    Since the upgrade I'm finding that my cart is not displaying any updates that are made to it, unless I force a recompile, which leads me to think that I am not forcing an update on the cache when I am making changes to the order.

    Thanks,

    Paul.

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    Hey Paul,

    It's a pretty fundamental change TBH. We swapped out the whole caching mechanism for a custom one that allows sliding expiration. Before we were just caching into Umbraco's own cache, but we needed more control over the cache so had to implement our own (though it's based technically on how the Umbraco isolated caches work).

    Hmm, if you are needing to restart the app pool to see the changes then it would suggest the changes are being made but the cache isn't updating for some reason.

    I'll have to give this a test.

    Matt

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    I've just tested on my local build and the orders seem to be updating OK in the checkout pages. I can increase/decrease quantities and remove items from the cart and all seems to update as expected.

    Are there any errors in your trace log?

    Matt

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    Matt,

    Nothing in the trace log.

    Because I am handling all cart updates in ajax I can see that it is passing updated order data back to the client (and then updating the totals etc as I would expect).

    If I then refresh the page it reverts back to the previous values, as though it has not saved the order. Restarting the app pool and then refreshing after this does display the updated order data.

    I have a couple of extension methods that I am using to add a product:

        public static BasketData AddItem(this OrderReadOnly orderRO, string productReference, decimal quantity)
        {
            using (var uow = VendrApi.Instance.Uow.Create())
            {
                var ret = orderRO.AsWritable(uow)
                    .AddProduct(productReference.GetProductSnapshot(), quantity, null, "", "", null)
                    .CompleteBasketAction(uow, BasketData.BasketAction.AddItem);
                ret.SetProduct(productReference);
                return ret;
            }
        }
    
        public static BasketData CompleteBasketAction(this Order order, IUnitOfWork uow, BasketData.BasketAction action)
        {
    
            //To do - Run basket checks...
            VendrApi.Instance.SaveOrder(order);
            uow.Complete();
            return new BasketData(action, order);
        }
    

    Is there anything that jumps out as to why this wouldn't work?

    I have also tries putting the uow.Complete() within the using statement rather than trying to pass the UOW as a parameter and the result is the same.

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    Do you have any front end caching in play at all? And what is your code for retrieving the order initially on page load?

    The AddProduct call seems kind of odd having to pass the snapshot and the null params. I think if you add a using Vendr.Core; statement at the top you'll get access to some more useful AddProduct extension methods where you won't have to supply those. Not sure this is the root of your issue though.

    Matt

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    I think those null parameters and empty strings are just a throwback to something I was doing previously, I have removed those now, with no effect.

    The only caching will be the default out of the box settings, as I have not changed anything.

    I'm using the following to get the order on page load...

    public class TopNav : ViewModelBase
    {
        public int BasketQty = 0;
        public bool BasketError = false;
        public string BasketTotal = "";
        public OrderReadOnly Order;
        public TopNav(IPublishedContent content) : base(content)
        {
            Order = VendrApi.Instance.GetOrCreateCurrentOrder(StoreId);
            BasketQty = 0;
            BasketError = false;
            BasketTotal = new Price(0, 0, Order.CurrencyId).Formatted().ToString();
            if (Order != null && (int)Order.TotalQuantity > 0)
            {
                BasketQty = (int)Order.TotalQuantity;
                BasketTotal = Order.SubtotalPrice.Value.Formatted().WithTax.ToString();
                BasketError = !Order.OrderCanProceed();
            }
        }
    }
    
  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    Hmm, that seems OK to me 🤔

    I'm not sure why it's working for me then and not you. Short of getting you to send me your project I'm not sure how else to debug this 🤔

    Matt

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    Hmmm. It's odd as it was working before I upgraded to 1.7.

    My surface controller looks like this:

    public class EcomSurfaceController : SurfaceController//, IRequiresSessionState
    {
        public string AddToBasket(string storeId, string product, int quantity = 1)
        {
            return EcomExtensions.GetOrderRO(storeId).AddItem(product, quantity).Serialize();
        }
    

    --

        public static OrderReadOnly GetOrderRO(string storeId)
        {
            return VendrApi.Instance.GetOrCreateCurrentOrder(storeId.AsGuid());
        }
    

    I assume that looks ok too?

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    Hey Paul,

    Yea, seems ok to me.

    Without debugging into what is actually happening and when things are actually changing I'm not sure what to suggest.

    You could try accessing the ICacheAccessor in Vendr and look in the EntityCaches for the order cache and check to see if it's getting added into the cache once the UoW transaction is complete.

    Effectively how our caching works within transactions is we have a global cache, then in a transaction, any changes to the cache are made to a temporary cache, then when the transaction completes, all the changed items in the temporary cache are copied over to the global cache. So if you can follow that flow you can check it's actually doing what it's supposed to do.

    Matt

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    Sorry Matt, Can you just give a really quick starting point as to how I could access the ICacheAccessor please?

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    Ok I'll have to have a hunt.

    I can see that when I update a qty on the cart the value in the DB is updating, so it appears that it's writing the data correctly....

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    Hi Paul,

    Sure, add ICacheAccessor as a parameter on your controllers constructor, then store it in a private readonly var. Then check it's EntityCaches property for the order cache and see if your updated order is in there and up to date.

    Matt

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    So would I get the Order cache by

    var c = _cache.EntityCaches.GetOrCreate<Order>();
    

    ?

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    Not quite. All entities have an internal object that holds their state so for orders that OrderState

    var c = _cache.EntityCaches.GetOrCreate<OrderState>();
    

    Matt

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    So,

    If I do a recompile, with a qty of 1 product in the order, then increase the quantity in the basket by one each time, my debug logging of the OrderState values from before calling "SetQuantity", before calling "uow.Complete" and after calling "uow.Complete" returns:

    BEFORE CHANGE QTY
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 1.0000
    BEFORE UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 1.0000
    AFTER UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 1.0000
    
    
    
    BEFORE CHANGE QTY
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    BEFORE UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    AFTER UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    
    
    
    BEFORE CHANGE QTY
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    BEFORE UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    AFTER UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    
    
    
    BEFORE CHANGE QTY
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    BEFORE UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    AFTER UOW.COMPLETE
    CART: HOICART-0475-0835-97XK
    LineId: 0aafaa23-1968-42ed-8a18-0b499db9701a
    QTY: 2
    

    Not sure if this tells me anything at all!

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    Well, it's telling you that the cache isn't getting updated so something is stopping it

  • Matt Brailsford 3051 posts 15816 karma points MVP 7x c-trib
    27 days ago
    Matt Brailsford
    0

    I'm kinda back to where I was earlier now though and really I think the only way I can get to the issue is if I can debug the project for myself and see what the problem is.

    Does the project contain any sensitive information? Would it be zippable so I can test it? You can send a link to [email protected].

  • Paul Crowdy 35 posts 96 karma points
    27 days ago
    Paul Crowdy
    0

    Thanks Matt - I’ll package it up and send a link over first thing tomorrow am.

Please Sign in or register to post replies

Write your reply to:

Draft