Tuesday, October 6, 2020

Sitecore XC 9.3 - Fix details in case if there is any issue while deleting the SXA site.

 Recently, I got an issue while deleting the site (SXA)



  Invoke-PreDeleteValidationStep : Cannot bind argument to parameter 'DefinitionItems' 
because it is null. At line:28 char:57 + ... $canRemove = Invoke-PreDeleteValidationStep 
$siteModules $SiteIt ... + ~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) 
[Invoke-PreDeleteValidationStep], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Invoke-PreDeleteValidationStep  
I didn't find any solution or details on google, Finally, I clicked on add modules and remove one unwanted module and clicked yes, basically that process refreshed the site again.

After that, I was able to delete the site.



It's a small trick but that really saved my time, I hope that will help other community members.

Sitecore XC (9.3) - Fix for OOM command not allowed when used memory

 During the CD2 configuration for one of the environment, I got below error 

ERR Error running script (call to f_2cf3a5ca51adf9b3b3500002e73e176dc3c54e26): @user_script:2: @user_script: 2: -OOM command not allowed when used memory > 'maxmemory'.   

I took reference from these links

  1. https://ma.ttias.be/redis-oom-command-not-allowed-used-memory-maxmemory/
  2. https://stackoverflow.com/questions/18430324/how-to-debug-the-error-oom-command-not-allowed-when-used-memory-maxmemory

After the investigation, I found this is because of the Redis cache memory issue, I have increased the size based on the analyzed load.

here are the steps to upload it -

# Redis configuration file example

# it in the usual form of 1k 5GB 4M and so forth:

# 1k => 1000 bytes

# 1kb => 1024 bytes

# 1m => 1000000 bytes

# 1mb => 1024*1024 bytes

# 1g => 1000000000 bytes

# 1gb => 1024*1024*1024 bytes

# units are case insensitive so 1GB 1Gb 1gB are all the same.

Navigate to the file C:\Program Files\Redis and update the value based on your analysis,

Monday, October 5, 2020

Sitecore 9.3 - Fix for SXA toolbox doesn't show in experience editor.

While working on SXA, you will always define the page design and partial design but in case if we need to add the placeholder key in the SXA layout, If we add the placeholder key before the 

@Html.Sxa().GridBody()

The application will not show the SXA components menu on the experience editor, to fix that we should keep this placeholder after the default placeholder.

Example - 



Sitecore XP 9.3 - Fix for Images are not showing in site only.

Recently, I got a request to check an urgent issue, the issue was that a few images in the page header and page content were not showing.

When I open that image in a new tab (through the direct URL) it didn't work but when I did the refresh on that Image in the same tab it shows the actual image, weird scenario yeah!!

I quickly check the request and response object of the site and individual tab (Only image link) and found a difference, While making a call from the website the request is sending the referee, As mentioned in the below screenshot.


Solution - the option is to remove the referrer for the particular page, I have added metadata and set the below value.

 <meta name="referrer" content ="no-referrer">  

that change resolve the issue,

We can also update the SXA layout for that


Note - this is a quick fix, but may create another issue of explicitly adding this tag, I will update in case of any further issue because of this change.

Happy Sitecore instance troubleshooting!!

Friday, October 2, 2020

Steps to update Sitecore SSL certificates (Sitecore XP 9.3)

It's a general requirement to update the security certificates for the website.

It's more enjoyable when we work on the Sitecore, consider multiple endpoints like CMS, xConnect, Identity servers and XC Roles. I again got a requirement to update the certificates and wanted to share this with the community so everyone can quickly do this without any issue or hurdles.

So let's get started the journey to update the certificate :) 

Steps  1 - Open the mmc.exe


 Àdd certification--> computer account


Install your certificate and you will see your certificate here-



Copy the thumbprint of the installed certificate 





Copy the thumbprint of the installed certificate and keep in a file.

Now, got to certificate and add all application pools identifier.




Make sure you enter the name in   IIS AppPool\App Pool identifier name format otherwise you wouldn't get the identifier.


Now, Search for the existing thumbprint on the site, You will find in below files.

  1. Identityserver\Config\production\Sitecore.IdentityServer.Host.xml
  2. CMsite\App_Config\ConnectionStrings.config
  3. xconnect\App_Config\AppSettings.config
  4. xconnect\App_Data\jobs\continuous\ProcessingEngine\App_Config\ConnectionStrings.config
  5. xconnect\App_Data\jobs\continuous\AutomationEngine\App_Config\ConnectionStrings.config

After replacing the file, got to IIS site and choose the correct certificate and restart the IIS.

that's it, It's very straightforward.

Troubleshooting - 

1. I got this error after updating the SSL certificate.

 1.     message: "An error has occurred.", exceptionMessage: "An error occurred while sending the request.",…}  
 1.     exceptionMessage: "An error occurred while sending the request."  
 2.     exceptionType: "System.Net.Http.HttpRequestException"  
 3.     innerException: {message: "An error has occurred.",…}  
 4.     message: "An error has occurred."  
 5.     stackTrace: "  at Sitecore.Xdb.Common.Web.Synchronous.SynchronousExtensions.SuspendContextLock[TResult](Func`1 taskFactory)  
 6.     ↵  at Sitecore.ExperienceAnalytics.Core.Repositories.ReferenceData.ReferenceDataSegmentReader.Get(IEnumerable`1 keys, NameValueCollection readingPreferences)  
 7.     ↵  at Sitecore.ExperienceAnalytics.Aggregation.Repositories.AggregationSegmentReader.Get(IEnumerable`1 keys, NameValueCollection readingPreferences)  
 8.     ↵  at Sitecore.ExperienceAnalytics.Api.RequestTypeResolver.GetReportSegments()  
 9.     ↵  at Sitecore.ExperienceAnalytics.Api.RequestTypeResolver.GetRequestType()  
 10.     ↵  at Sitecore.ExperienceAnalytics.Api.Http.ModelBinding.ReportQueryModelBinder.GetModelFromBindingContext(HttpActionContext actionContext, ModelBindingContext bindingContext)  
 11.     ↵  at Sitecore.ExperienceAnalytics.Api.Http.ModelBinding.ReportQueryModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)  
 12.     ↵  at System.Web.Http.ModelBinding.ModelBinderParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)  
 13.     ↵  at System.Web.Http.Controllers.HttpActionBinding.<ExecuteBindingAsyncCore>d__12.MoveNext()  
 14.     ↵--- End of stack trace from previous location where exception was thrown ---  
 15.     ↵  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
 16.     ↵  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
 17.     ↵  at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()  
 18.     ↵--- End of stack trace from previous location where exception was thrown ---  
 19.     ↵  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
 20.     ↵  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
 21.     ↵  at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()  
 22.     ↵--- End of stack trace from previous location where exception was thrown ---  
 23.     ↵  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
 24.     ↵  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
 25.     ↵  at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()  
 26.     ↵--- End of stack trace from previous location where exception was thrown ---  
 27.     ↵  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
 28.     ↵  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
 29.     ↵  at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()  
 30.     ↵--- End of stack trace from previous location where exception was thrown ---  
 31.     ↵  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
 32.     ↵  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
 33.     ↵  at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()  
 34.     ↵--- End of stack trace from previous location where exception was thrown ---  
 35.     ↵  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
 36.     ↵  at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()  
 37.     ↵--- End of stack trace from previous location where exception was thrown ---  
 38.     ↵  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
 39.     ↵  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
 40.     ↵  at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"  

A few more errors -
 {"message":"An error has occurred.","exceptionMessage":"An error occurred while sending the request.","exceptionType":"System.Net.Http.HttpRequestException","stackTrace":"  at Sitecore.Xdb.Common.Web.Synchronous.SynchronousExtensions.SuspendContextLock[TResult](Func`1 taskFactory)\r\n  at Sitecore.ExperienceAnalytics.Core.Repositories.ReferenceData.ReferenceDataSegmentReader.Get(IEnumerable`1 keys, NameValueCollection readingPreferences)\r\n  at Sitecore.ExperienceAnalytics.Aggregation.Repositories.AggregationSegmentReader.Get(IEnumerable`1 keys, NameValueCollection readingPreferences)\r\n  at Sitecore.ExperienceAnalytics.Api.RequestTypeResolver.GetReportSegments()\r\n  at Sitecore.ExperienceAnalytics.Api.RequestTypeResolver.GetRequestType()\r\n  at Sitecore.ExperienceAnalytics.Api.Http.ModelBinding.ReportQueryModelBinder.GetModelFromBindingContext(HttpActionContext actionContext, ModelBindingContext bindingContext)\r\n  at Sitecore.ExperienceAnalytics.Api.Http.ModelBinding.ReportQueryModelBinder.BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)\r\n  at System.Web.Http.ModelBinding.ModelBinderParameterBinding.ExecuteBindingAsync(ModelMetadataProvider metadataProvider, HttpActionContext actionContext, CancellationToken cancellationToken)\r\n  at System.Web.Http.Controllers.HttpActionBinding.<ExecuteBindingAsyncCore>d__12.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.<ExecuteAsync>d__5.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.<ExecuteAuthorizationFilterAsyncCore>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.HandleNonSuccessAndDebuggerNotification(Task task)\r\n  at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>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.HandleNonSuccessAndDebuggerNotification(Task task)\r\n  at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>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.HandleNonSuccessAndDebuggerNotification(Task task)\r\n  at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.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.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.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.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()","innerException":{"message":"An error has occurred.","exceptionMessage":"The request was aborted: Could not create SSL/TLS secure channel.","exceptionType":"System.Net.WebException","stackTrace":"  at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)\r\n  at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)"}  
 Exception: Sitecore.XConnect.XdbCollectionUnavailableException  
 Message: The HTTP response was not successful: Forbidden  
 Source: Sitecore.Xdb.Common.Web  
   at Sitecore.Xdb.Common.Web.Synchronous.SynchronousExtensions.SuspendContextLock[TResult](Func`1 taskFactory)  
   at Sitecore.XConnect.Client.XConnectSynchronousExtensions.SuspendContextLock(Func`1 taskFactory)  
   at Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.Initialize(XmlNode configNode)  
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert, IFactoryHelper helper)  
   at Sitecore.Configuration.DefaultFactory.CreateObject(XmlNode configNode, String[] parameters, Boolean assert)  
   at Sitecore.Configuration.DefaultFactory.CreateObject(String configPath, String[] parameters, Boolean assert)  
   at Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient(String clientConfigPath)  
   at Sitecore.Analytics.Aggregation.XConnect.DefaultXdbContextFactory.CreateReadOnly()  
   at Sitecore.Analytics.Processing.AsyncPoolScheduler`2..ctor(IAsyncProcessingPool`1 pool, IXdbContextFactory xdbContextFactory, ExpandOptions options, Int16 maxBatchSize, BaseLog log)  
   at Sitecore.Analytics.Aggregation.InteractionAggregationAgent.<ExecuteCoreAsync>d__15.MoveNext()  
 --- End of stack trace from previous location where exception was thrown ---  
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
   at Sitecore.Analytics.Core.Agent.<ExecuteAsync>d__1.MoveNext()  
 --- End of stack trace from previous location where exception was thrown ---  
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
   at Sitecore.Analytics.Core.AsyncBackgroundService.<ExecuteAgentAsync>d__22.MoveNext()  
 --- End of stack trace from previous location where exception was thrown ---  
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()  
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)  
   at Sitecore.Analytics.Core.AsyncBackgroundService.<RunAsync>d__26.MoveNext()  


Fix - I missed to include the identifier role in the certificate, After including that role this issue got resolved,



Saturday, September 19, 2020

Fix for the Domain is null and Invalid or missing value for property.


 Recently, I have updated my local instance and while doing the new registration or login got the below error

The Domain is null and is probably not defined in Domain Manager

When I checked my domain configuration under site settings

/sitecore/content/Tenant/Sitecore/Settings/Site Grouping/Site

I found the reference of the domain didn't exist on my local system, I created a new domain through the admin panel here

After fixing that, during the registration, I got a diff error

 {  
  "IsSignupFlow": false,  
  "UserName": null,  
  "Errors": [  
   "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator."  
  ],  
  "HasErrors": true,  
  "HasInfo": false,  
  "HasWarnings": false,  
  "Info": [  
  ],  
  "Success": false,  
  "Url": null,  
  "Warnings": [  
  ],  
  "ContentEncoding": null,  
  "ContentType": null,  
  "Data": null,  
  "JsonRequestBehavior": 1,  
  "MaxJsonLength": null,  
  "RecursionLimit": null  
 }  
I opened my session in a new incognito window and found below errors -

 {  
  "IsSignupFlow": false,  
  "UserName": null,  
  "Errors": [  
   "Invalid or missing value for property \u0027Domain\u0027."  
  ],  
  "HasErrors": true,  
  "HasInfo": false,  
  "HasWarnings": false,  
  "Info": [  
  ],  
  "Success": false,  
  "Url": null,  
  "Warnings": [  
  ],  
  "ContentEncoding": null,  
  "ContentType": null,  
  "Data": null,  
  "JsonRequestBehavior": 1,  
  "MaxJsonLength": null,  
  "RecursionLimit": null  
 }  
I updated the existing domain in site groping,  to see if it's working because, because I haven't added this domain in the commerce configuration .
 {  
  "IsSignupFlow": false,  
  "UserName": null,  
  "Errors": [  
   "Customer \u0027Storefront\\jitusonijk@gmail.com\u0027 already exists."  
  ],  
  "HasErrors": true,  
  "HasInfo": false,  
  "HasWarnings": false,  
  "Info": [  
  ],  
  "Success": false,  
  "Url": null,  
  "Warnings": [  
  ],  
  "ContentEncoding": null,  
  "ContentType": null,  
  "Data": null,  
  "JsonRequestBehavior": 1,  
  "MaxJsonLength": null,  
  "RecursionLimit": null  
 }  
So abve message is because I had the same user already registered, I did a new registration and it worked for me.

The issue/learning was - If you create a new domain configuration please make sure that we need to update the site groping and policies accordingly.

PlugIn.AdventureWorks.CommerceAuthoring-1.0.0.json
PlugIn.Habitat.CommerceAuthoring-1.0.0.json
PlugIn.YourSite.CommerceAuthoring-1.0.0.json

 


Wednesday, September 16, 2020

Sitecore Experience Commerce - Steps to update custom values through - GetEntityView and DoUxAction APIs.

There are a few options to extend the Sitecore commerce entities,  OOTB Sitecore XC provided below entities.

  1.  Sitecore.Commerce.Plugin.Catalog.SellableItem
  2.  Sitecore.Commerce.Plugin.Catalog.Catalog
  3.  Sitecore.Commerce.Plugin.Catalog.Category
  4.  Sitecore.Commerce.Plugin.Promotions.PromotionBook
  5.  Sitecore.Commerce.Plugin.Promotions.Promotion
  6.  Sitecore.Commerce.Plugin.Pricing.PriceBook
  7.  Sitecore.Commerce.Plugin.Pricing.PriceCard
  8.  Sitecore.Commerce.Plugin.Customers.Customer
  9.  Sitecore.Commerce.Plugin.Orders.Order

If you are working in the commerce world, you will see a requirement to extend these entities, the requirement can be an example below.

1,  Add invoice link to the order - Add a new field on order entities to show the invoice link or status from the backend system.

2. Add a new field on customer entities to show the preferred time for the call, Membership type like gold, silver etc.

3. Extend the sellable item (The most common one) to add more fields like custom properties for Color, notes etc.

For updating the order usually, we should use the minion jobs to read the current status and update from the backend system but sometimes you need to update those details from the outer side. Here are a few easy tips.

To update any field values of entities like Order, Customer you can use the GetEntityVIew to get the Entry and 

URL will be like this  

https://commerceauthoring.XX.dev.com/api/GetEntityView()- h

Request input-

{  
  "entityId": "Entity-Customer-f26e9063ba38461bafcf97fe4a115830",  
  "viewName": "EditView",  
  "forAction": "EditView",  
  "itemId": "Composer-82bd424ddb274945912dca6fb71cea4b"  
 }  
We need to pass the Customer or Entity and name of the Composer template-

The response will be an complete entity, We can keep the response in an object and update the value and after that can call the

 https://commerceauthoring.XXX.com.dev.com/api/DoUxAction()

and post the updated view, that will update the value in the entiry.

 {  
  "@odata.context": "https://commerceauthoring.XXX.com.dev.com/Api/$metadata#Sitecore.Commerce.EntityViews.EntityView",  
  "@odata.type": "#Sitecore.Commerce.EntityViews.EntityView",  
  "Name": "EditView",  
  "Policies": [  
  ],  
  "DisplayName": "Edit View",  
  "EntityId": "Entity-SellableItem-demohandtowel1",  
  "EntityVersion": 4,  
  "Action": "EditView",  
  "ItemId": "Composer-82bd424ddb274945912dca6fb71cea4b",  
  "VersionedItemId": "Composer-82bd424ddb274945912dca6fb71cea4b-4",  
  "SelectedChildView": {  
   "Name": "",  
   "Policies": [  
   ]  
  },  
  "DisplayRank": 500,  
  "UiHint": "Flat",  
  "Icon": "chart_column_stacked",  
  "Properties": [  
   {  
    "Name": "Version",  
    "Policies": [  
    ],  
    "DisplayName": "Version",  
    "Value": "1",  
    "IsHidden": true,  
    "OriginalType": "System.Int32",  
    "IsReadOnly": true,  
    "UiType": "",  
    "IsRequired": true  
   },  
   {  
    "Name": "LaunchDate",  
    "Policies": [  
    ],  
    "DisplayName": "Launch Date",  
    "Value": "2020-09-16T14:26:00.5386742+00:00",  
    "IsHidden": false,  
    "OriginalType": "System.DateTimeOffset",  
    "IsReadOnly": false,  
    "UiType": "",  
    "IsRequired": true  
   },  
   {  
    "Name": "DealerName",  
    "Policies": [  
    ],  
    "DisplayName": "Dealer Name",  
    "Value": "",  
    "IsHidden": false,  
    "OriginalType": "System.String",  
    "IsReadOnly": false,  
    "UiType": "",  
    "IsRequired": true  
   }  
  ],  
  "ChildViews": [  
  ]  
 }  
the get GetEntityView will always create a new version in case of edit, so there would be any issue for the concurrency, the same request response can be used to update the entity with the latest values.

Note:- Although this is not a recommended option. 
Ideally, all these changes should go inside the commerce engine.

This information is just an example if there is any need to update data from the external API or need for front end extension.