Copied to clipboard

Flag this post as spam?

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


  • Claudiu Bria 34 posts 146 karma points
    May 08, 2017 @ 21:09
    Claudiu Bria
    0

    ysod after deleting logged-in customer

    Hi Rusty,

    After I created a customer using the /account/ registration page, I got the newly created customer to be the current logged-in customer.

    I then use the backoffice interface and - logged-in as an admin - I delete both the member and the Merchello Customer.

    When I try to get back from the backoffice to the webstore interface on the first refresh of the page i get the ysod:

    Server Error in '/' Application.
    
    Object reference not set to an instance of an object.
    
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
    
    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
    
    Source Error: 
    
    
    Line 117:            var member = _memberService.GetById(memberId); Line 118: Line 119:            if (MerchelloConfiguration.Current.CustomerMemberTypes.Any(x => x == member.ContentTypeAlias)) Line 120:            { Line 121:             base.EnsureCustomerCreationAndConvertBasket(customer);
    
    Source File: C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\CustomerContext.cs    Line: 119 
    
    Stack Trace: 
    
    
    [NullReferenceException: Object reference not set to an instance of an object.]    Merchello.Web.<>c__DisplayClass9_0.<EnsureCustomerCreationAndConvertBasket>b__0(String x) in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\CustomerContext.cs:119   System.Linq.Enumerable.Any(IEnumerable`1 source, Func`2 predicate)
    +146    Merchello.Web.CustomerContext.EnsureCustomerCreationAndConvertBasket(ICustomerBase customer) in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\CustomerContext.cs:119   Merchello.Web.Pluggable.CustomerContextBase.TryGetCustomer(Guid key) in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\Pluggable\CustomerContextBase.cs:277 Merchello.Web.Pluggable.CustomerContextBase.Initialize() in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\Pluggable\CustomerContextBase.cs:554 Merchello.Web.Pluggable.CustomerContextBase..ctor(IMerchelloContext merchelloContext, UmbracoContext umbracoContext) in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\Pluggable\CustomerContextBase.cs:99 Merchello.Web.CustomerContext..ctor(UmbracoContext umbracoContext) in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\CustomerContext.cs:54
    
    [TargetInvocationException: Exception has been thrown by the target of an invocation.]    Merchello.Web.Pluggable.PluggableObjectHelper.GetInstance(String configurationAlias, Object[] ctrArgValues) in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\Pluggable\PluggableObjectHelper.cs:110 Merchello.Web.Pluggable.PluggableObjectHelper.GetInstance(String configurationAlias, Object param1) in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\Pluggable\PluggableObjectHelper.cs:50 Merchello.Web.Mvc.MerchelloTemplatePage.get_CurrentCustomer() in C:\Clax\VSOW\Ajour.no\AjourCms1\Merchello.Web\Mvc\MerchelloTemplatePage.cs:32 ASP._Page_Views_Shared__Header_cshtml.Execute() in c:\Clax\VSOW\Ajour.no\AjourCms1\AjourCms1\Views\Shared\_Header.cshtml:57 System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +198    System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105    System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +90    System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235    System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107    Umbraco.Core.Profiling.ProfilingView.Render(ViewContext viewContext, TextWriter writer) +113    System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection) +277    System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData) +91 System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName) +31    ASP._Page_Views_FastTrack_cshtml.Execute() in c:\Clax\VSOW\Ajour.no\AjourCms1\AjourCms1\Views\FastTrack.cshtml:15    System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +198    System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +105    System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +90    System.Web.WebPages.<>c__DisplayClass3.<RenderPageCore>b__2(TextWriter writer) +232    System.Web.WebPages.HelperResult.WriteTo(TextWriter writer) +10    System.Web.WebPages.WebPageBase.Write(HelperResult result) +80    System.Web.WebPages.WebPageBase.RenderSurrounding(String partialViewName, Action`1 body) +63    System.Web.WebPages.WebPageBase.PopContext() +237    System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +98    System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +235    System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +107    Umbraco.Core.Profiling.ProfilingView.Render(ViewContext viewContext, TextWriter writer) +113    System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
    +290    System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56    System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +420   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +52    System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
    +173    System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100    System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +10    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27    System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +22    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49    System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26    System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10    System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21    System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +29    System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
    +28    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9    System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
    +9765045    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
    
    Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1637.0
    

    The exception occurs because in Merchello.Web/CustomerContext.cs, the memberId gets -1 and then the member object gets null:

    protected override void EnsureCustomerCreationAndConvertBasket(ICustomerBase customer)
    {
        if (!customer.IsAnonymous) return;
    
        var memberId = Convert.ToInt32(this.MembershipProviderKey(customer.Key));
        var member = _memberService.GetById(memberId);
    
        if (MerchelloConfiguration.Current.CustomerMemberTypes.Any(x => x == member.ContentTypeAlias))
        {
            base.EnsureCustomerCreationAndConvertBasket(customer);
        }
    }
    

    I would say even further that in this case the logic that allows this to happen is in the TryGetCustomer(Guid guid) method of Merchello.Web/Pluggable/CustomerContextBase.cs:

        // Check the cache for a previously retrieved customer.
        // There can be many requests for the current customer during a single request.
        if (customer != null)
        {
            CurrentCustomer = customer;
    
            // No we need to assert whether or not the authentication status has changed
            // during this request - the user either logged in or has logged out.
            if (customer.IsAnonymous)
            {
                // We have an anonymous customer but the user is now authenticated so we may want to create an 
                // customer and convert the basket
                if (isLoggedIn)
                {
                    this.EnsureCustomerCreationAndConvertBasket(customer);
                }
            }
    

    While this logic here makes sense for detecting an AnonymousCustomer converting into a Customer, it is also triggerred when a Customer "would convert into an AnonymousCustomer" - because deleting the MerchelloCustomer object and the related Member of a Customer should in theory be the reverse operation - but in this case is failing.

    I could not find a good resolution for this yet, all i could do so far is to add the member check, instead of:

        if (MerchelloConfiguration.Current.CustomerMemberTypes.Any(x => x == member.ContentTypeAlias))
    

    now I have:

        if (member!=null && MerchelloConfiguration.Current.CustomerMemberTypes.Any(x => x == member.ContentTypeAlias))
    

    But that change is directly inside of your code in Merchello.Web/CustomerContext.cs, whereas I would very much like to have something in my project code, something like a removal or an initialization of the cached customer on member deletion in UmbracoEventHandler.cs, something like:

        public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            ShipmentService.StatusChanged += ShipmentServiceStatusChanged;
            SmtpNotificationGatewayMethod.Sending += SmtpNotificationOnSending;
            SendGridEmailNotificationGatewayMethod.Sending += SendGridEmailNotificationOnSending;
            MemberService.Created += MemberService_Created;
            MemberService.Deleting += MemberService_Deleting;
        }
    
    private void MemberService_Deleting(IMemberService sender, Umbraco.Core.Events.DeleteEventArgs<IMember> e)
    {
        var memberService = sender;
        var members = e.DeletedEntities;
        var customerContext = new CustomerContext(UmbracoContext.Current);
        if (MerchelloContext.HasCurrent)
        {
            var customerService = MerchelloContext.Current.Services.CustomerService;
            foreach (var member in members)
            {
                var customer = customerService.GetByLoginName(member.Email);
                if (customer != null && !customer.IsAnonymous && customerContext.CurrentCustomer.Key == customer.Key)
                {
                    customerContext.Reinitialize(customer);
                    var customerNew = customerService.CreateAnonymousCustomerWithKey();
                    customerContext.Reinitialize(customerNew);
                    //curre
                    //customerContext.CurrentCustomer. = customer;
                    //var customerContextData = new CustomerContextData()
                    //{
                    //    Key = customer.Key
                    //};
                    //MerchelloContext.Current.Cache.RequestCache.
    
                    //CacheCustomer(customer);
                }
            }
        }
    }
    

    which doesn't look to work.

    Any ideas please Rusty ? How can i fix this from outside Merchello's code ?

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    May 09, 2017 @ 04:21
    Rusty Swayne
    0

    Hey Claudiu,

    If you delete the member and the customer from the back office you probably don't need to start to reinitialize the CustomerContext - that should take care of itself.

    However, it may have something to do with the CustomerContext caching (this will be refactored in v3.0 http://issues.merchello.com/youtrack/issue/M-1132) and/or potentially a cookie not being updated - which would depend on how you are testing. Example if you are running through as a customer and then logging in with the same browser, deleting the customer and member and going back in the same browser and looking again from a customer perspective.

    This issue was likely introduced https://github.com/rustyswayne/Merchello/blob/merchello-dev/src/Merchello.FastTrack.Ui/App_Plugins/Merchello/config/merchello.config#L31 to make basket retention for anonymous customers configurable.

    Can you verify that this issue only happens if you don't log out with the customer before you delete them and you are using the same browser?

  • Claudiu Bria 34 posts 146 karma points
    May 09, 2017 @ 07:39
    Claudiu Bria
    0

    Hi Rusty,

    Thank you for your quick response.

    I just checked on 2 different scenarios:

    • Chrome for customer registration and webstore interface and IE for backoffice
    • IE for customer registration and webstore interface and Edge for backoffice

    In both scenarios i did not logout the user from the webstore interface after registration, instead I just deleted the member and the merchello customer from the backoffice and right after that, back to the webstore i refreshed the root / page.

    The issue is there in both scenarios. The exception is thrown the same as explained before.

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    May 11, 2017 @ 14:01
    Rusty Swayne
    0

    Ok - that makes sense. Would you might logging this as a minor issue on https://issues.merchello.com

    I don't think it's a critical issue as most customers won't be back office administrators ;-)

Please Sign in or register to post replies

Write your reply to:

Draft