Developer forum

Forum » Dynamicweb 9.0 Upgrade issues » context.customer is NULL in price provider

context.customer is NULL in price provider

Peter Leleulya
Peter Leleulya
Reply

Hi guys,

I had to rewrite some price providers due to obsolete methods.

I had to use the FindPrice with the PriceContext parameter.

But when I debug and get into the FindPrice method the value of Customer within the price context is NULL even when there is a current user logged in ...
I would have expected the price context current user to be the currently loggedin user, or is that a misinterpretation and do I have to do something to get it filled?

I now added a line and worked with that: var customer = context?.Customer ?? User.GetCurrentUser(PagePermissionLevels.Frontend);

Additional, within this method I need the product number to do my magic. In the obsolete method I have the product and all its properties.
In this new method for each call I have to first get the product by id and variantid to get its number ... doesn't feel right ...


Replies

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

Hi Peter,

The price context depends on the context ;-)

When rendering prices in the product catalog then PriceContext.Customer is the current user.
When rendering prices in the shopping cart then PriceContext.Customer is the user associated with the cart/order instance (Order.CustomerAccessUserId).

The reason for the difference is that an order might be processed in a context where the current user is not available or where the order customer is not the current user.
Your custom price provider might be called in these scenarios.

If User.GetCurrentUser(PagePermissionLevels.Frontend) works for you then go with that, but I would not recommend doing so.
Instead I would suggest that you ensure that the order has a correct user id and then PriceContext.Customer will contain the correct user when your price provider is called.

If you think that it is a bug then please share some more details about how to reproduce the issue and we can take a closer look.

/Morten

 
Peter Leleulya
Peter Leleulya
Reply

Hi morten, 

What order, I'm trying to get prices. Why would there be an order?
Or is there some context value I need to set?

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

A shopping cart (order) has lines with products and prices. When these prices are calculated the price providers are called with price context information from the cart (customer, country, etc.). If you don't use shopping carts (or other types of orders) in your website then I guess there will not be an order.

It would be very helpful if you could provide more information about when and where the issue occurs.
"when I debug and get into the FindPrice method the value of Customer within the price context is NULL even when there is a current user logged in"
What's the call stack at that point where the value of Customer is null? You can get that by calling System.Environment.StackTrace.ToString() in your price provider.

 
Peter Leleulya
Peter Leleulya
Reply

Hi Morten,

I found out it might have to do with our custom implementation of the product list.
Perhaps yu have a tip for me what to do.

I put a breakpoint in the FindPrice method again and found out that when I log in and get the user assortment (custom) I break having the user set in the price context correctly.
Then when I navigate to the product list page I break having the user to be NULL in the price context.
I pasted the stack from that moment below.
When I navigate to a product detail page I break having the user set in the price context correctly.
When I add to cart and go to the cart I break having the user set in the price context correctly.
When I went to a product list again I break having the user to be NULL again in the price context.

The product list page has a paragraph with a Product Catalog for ViewModel APP placed on it, all properties set to "Include all" for the moment.
But in the list view template we do some magic.
We pass the model to a method which returns a custom extended model, but it doesn't hit the FindPrice there!
When the template uses the extended model values to show the products and wants to show a price I break having the user to be NULL in the price context.
The object we iterate through is a List<MasterWithVariantsModel>
MasterWithVariantsModel is some master data, List<Dynamicweb.Ecommerce.Produts.Product> and some other lists
The list of Product is printed in the template along with data from the other lists.

Can you come up with any reason why the user would be NULL?

Stack:

   at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
   at System.Environment.get_StackTrace()
   at MyProject.Application.CustomCode.Providers.SapPriceProvider.FindPrice(PriceContext context, PriceProductSelection selection) in C:\Projects_GIT\MyProject\MyProject.Application\CustomCode\Providers\SapPriceProvider.cs:line 40
   at Dynamicweb.Ecommerce.Prices.PriceManager.FindPriceInternal(PriceProvider provider, PriceContext context, PriceProductSelection selection, Boolean isInformative)
   at Dynamicweb.Ecommerce.Prices.PriceManager.FindPrice(PriceContext context, PriceProductSelection selection, Boolean isInformative)
   at Dynamicweb.Ecommerce.Prices.PriceManager.GetPrice(PriceContext context, Product product, String unitId, Int64 stockLocationId)
   at Dynamicweb.Ecommerce.Prices.PriceManager.GetPrice(Product product, String currencyCode, String countryCode, String unitId, Int32 userId, String shopId, StockLocation stockLocation)
   at Dynamicweb.Ecommerce.Products.Product.get_Price()
   at CompiledRazorTemplates.Dynamic.RazorEngine_4ee06cad6eb44079b90bdfc6279bcc7d.Execute() in C:\Projects_GIT\MyProject\MyProject.Application\Files\Templates\Designs\MyProject\eCom\ProductCatalog\ProductViewListFacets.cshtml:line 218
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
   at Dynamicweb.Rendering.Template.Output()
   at Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.RenderProductList(ProductCatalogSettings settings, String groupId, Boolean feed)
   at Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.GetContent()
   at Dynamicweb.Frontend.Content.GetModuleOutput(Paragraph paragraph, PageView pageview)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_fdfe45703b2e4dcea800102ea60d653b.Execute() in C:\Projects_GIT\MyProject\MyProject.Application\Files\Templates\Designs\MyProject\Paragraph\ModuleOnly.cshtml:line 2
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
   at Dynamicweb.Rendering.Template.Output()
   at Dynamicweb.Frontend.Content.RenderParagraph(Paragraph paragraph, ContainerInfo containerInfo, Layout layout, GridColumnViewModel column)
   at Dynamicweb.Frontend.Content.CreateContent(IList`1 paragraphs)
   at Dynamicweb.Frontend.Content.CreateContent(Int32 contentId)
   at Dynamicweb.Frontend.ContentViewModelFactory.CreatePageViewModel(PageView pageView)
   at Dynamicweb.Frontend.PageView.SetPageTemplateValues()
   at Dynamicweb.Frontend.PageView.Output()
   at Dynamicweb.AspNet.DynamicwebHttpHandler.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
   at System.Web.HttpApplication.PipelineStepManager.ResumeSteps(Exception error)
   at System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb)
   at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
   at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
   at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)

 

 

 
Peter Leleulya
Peter Leleulya
Reply

Hi Morten,

I found out it might have to do with our custom implementation of the product list.
Perhaps yu have a tip for me what to do.

I put a breakpoint in the FindPrice method again and found out that when I log in and get the user assortment (custom) I break having the user set in the price context correctly.
Then when I navigate to the product list page I break having the user to be NULL in the price context.
I pasted the stack from that moment below.
When I navigate to a product detail page I break having the user set in the price context correctly.
When I add to cart and go to the cart I break having the user set in the price context correctly.
When I went to a product list again I break having the user to be NULL again in the price context.

The product list page has a paragraph with a Product Catalog for ViewModel APP placed on it, all properties set to "Include all" for the moment.
But in the list view template we do some magic.
We pass the model to a method which returns a custom extended model, but it doesn't hit the FindPrice there!
When the template uses the extended model values to show the products and wants to show a price I break having the user to be NULL in the price context.
The object we iterate through is a List<MasterWithVariantsModel>
MasterWithVariantsModel is some master data, List<Dynamicweb.Ecommerce.Produts.Product> and some other lists
The list of Product is printed in the template along with data from the other lists.

Can you come up with any reason why the user would be NULL?

Stack:

   at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
   at System.Environment.get_StackTrace()
   at MyProject.Application.CustomCode.Providers.SapPriceProvider.FindPrice(PriceContext context, PriceProductSelection selection) in C:\Projects_GIT\MyProject\MyProject.Application\CustomCode\Providers\SapPriceProvider.cs:line 40
   at Dynamicweb.Ecommerce.Prices.PriceManager.FindPriceInternal(PriceProvider provider, PriceContext context, PriceProductSelection selection, Boolean isInformative)
   at Dynamicweb.Ecommerce.Prices.PriceManager.FindPrice(PriceContext context, PriceProductSelection selection, Boolean isInformative)
   at Dynamicweb.Ecommerce.Prices.PriceManager.GetPrice(PriceContext context, Product product, String unitId, Int64 stockLocationId)
   at Dynamicweb.Ecommerce.Prices.PriceManager.GetPrice(Product product, String currencyCode, String countryCode, String unitId, Int32 userId, String shopId, StockLocation stockLocation)
   at Dynamicweb.Ecommerce.Products.Product.get_Price()
   at CompiledRazorTemplates.Dynamic.RazorEngine_4ee06cad6eb44079b90bdfc6279bcc7d.Execute() in C:\Projects_GIT\MyProject\MyProject.Application\Files\Templates\Designs\MyProject\eCom\ProductCatalog\ProductViewListFacets.cshtml:line 218
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
   at Dynamicweb.Rendering.Template.Output()
   at Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.RenderProductList(ProductCatalogSettings settings, String groupId, Boolean feed)
   at Dynamicweb.Ecommerce.ProductCatalog.ProductCatalogFrontend.GetContent()
   at Dynamicweb.Frontend.Content.GetModuleOutput(Paragraph paragraph, PageView pageview)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.LazyInitValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_fdfe45703b2e4dcea800102ea60d653b.Execute() in C:\Projects_GIT\MyProject\MyProject.Application\Files\Templates\Designs\MyProject\Paragraph\ModuleOnly.cshtml:line 2
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
   at Dynamicweb.Rendering.Template.Output()
   at Dynamicweb.Frontend.Content.RenderParagraph(Paragraph paragraph, ContainerInfo containerInfo, Layout layout, GridColumnViewModel column)
   at Dynamicweb.Frontend.Content.CreateContent(IList`1 paragraphs)
   at Dynamicweb.Frontend.Content.CreateContent(Int32 contentId)
   at Dynamicweb.Frontend.ContentViewModelFactory.CreatePageViewModel(PageView pageView)
   at Dynamicweb.Frontend.PageView.SetPageTemplateValues()
   at Dynamicweb.Frontend.PageView.Output()
   at Dynamicweb.AspNet.DynamicwebHttpHandler.ProcessRequest(HttpContext context)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
   at System.Web.HttpApplication.PipelineStepManager.ResumeSteps(Exception error)
   at System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb)
   at System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
   at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
   at System.Web.Hosting.UnsafeIISMethods.MgdIndicateCompletion(IntPtr pHandler, RequestNotificationStatus& notificationStatus)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)
   at System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr rootedObjectsPointer, IntPtr nativeRequestContext, IntPtr moduleData, Int32 flags)

 

 

 
Peter Leleulya
Peter Leleulya
Reply

This page crashed when adding my comment, ending up to be added twice ... sorry for that.

 
Morten Bengtson Dynamicweb Employee
Morten Bengtson
Reply

Hi Peter,

Thanks for the details. It was very helpful.

I have found the cause of the problem and will try to figure out how to fix that.
Until then you can make a small change in the template to get the correct price...

The best solution would be to use the ProductViewModel.Price property, if possible...

foreach(ProductViewModel product in Model.Products)
{
    PriceViewModel price = product.Price;
}

Otherwise, you can replace the call to product.Price with this:

PriceInfo price = Dynamicweb.Ecommerce.Prices.PriceManager.GetPrice(product, Common.Context.Currency.Code, Common.Context.Country.Code2, User.GetCurrentExtranetUserId());

... or if you prefer using something that is not marked as obsolete...

PriceContext priceContext = new PriceContext(Common.Context.Currency, Common.Context.Country, Services.Shops.GetShop(Pageview.Area.EcomShopId), User.GetCurrentExtranetUser(), Common.Context.ReverseChargeForVatEnabled, Common.Context.OrderTime);
PriceInfo price = product.GetPrice(priceContext);

I know, neither of these last two solutions are pretty, but it's the best I can come up with right now. Sorry about that.
We'll try to figure out a better way to handle this.

Best regards,
Morten

 
Peter Leleulya
Peter Leleulya
Reply

Hi Morten,

Thanks for your response.

 

You must be logged in to post in the forum