EPiServer.Commerce.FindSearchProvider.FindSearchQueryBuilder bug

Vote:
 

Using:

  • EPiServer.Commerce.Core 9.9.0
  • EPiServer.CommerceManager 9.9.0
  • EPiServer.Find 11.1.1.4013
  • EPiServer.Commerce.FindSearchProvider 8.12

Have following exception in commerce manager catalog search view:

find search provider exception example

exception:

[NullReferenceException: Object reference not set to an instance of an object.]
   EPiServer.Commerce.FindSearchProvider.FindSearchQueryBuilder..ctor(IClient client, ISearchCriteria criteria) +362
   EPiServer.Commerce.FindSearchProvider.FindSearchProvider.Search(String applicationName, ISearchCriteria criteria) +46
   Mediachase.Search.SearchManager.Search(ISearchCriteria criteria) +315
   Mediachase.Commerce.Manager.Catalog.CatalogEntrySearch.BindGrid(Boolean retryOnSearchException) +843
   Mediachase.Commerce.Manager.Catalog.CatalogEntrySearch.CurrentListView_PagePropertiesChanged(Object sender, EventArgs e) +14
   System.Web.UI.WebControls.ListView.OnPagePropertiesChanged(EventArgs e) +126
   System.Web.UI.WebControls.ListView.SetPageProperties(Int32 startRowIndex, Int32 maximumRows, Boolean databind) +151
   Mediachase.Commerce.Manager.Core.Controls.EcfListViewControl.Page_Load(Object sender, EventArgs e) +1032
   System.Web.UI.Control.OnLoad(EventArgs e) +109
   System.Web.UI.Control.LoadRecursive() +68
   System.Web.UI.Control.LoadRecursive() +165
   System.Web.UI.Control.LoadRecursive() +165
   System.Web.UI.Control.LoadRecursive() +165
   System.Web.UI.Control.LoadRecursive() +165
   System.Web.UI.Control.LoadRecursive() +165
   System.Web.UI.Control.LoadRecursive() +165
   System.Web.UI.Control.LoadRecursive() +165
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4498

Mediachase.Search.config:




  
    
      
    
  
  
    
  
#145703
Mar 10, 2016 12:21
Vote:
 
// Generated by .NET Reflector from C:\Projects\xxx\lib\EPiServer.Commerce.FindSearchProvider.8.12.0\lib\net45\EPiServer.Commerce.FindSearchProvider.dll
namespace EPiServer.Commerce.FindSearchProvider
{
    using EPiServer.Commerce.FindSearchProvider.LocalImplementation;
    using EPiServer.Find;
    using EPiServer.Globalization;
    using Mediachase.Commerce;
    using Mediachase.Search;
    using Mediachase.Search.Extensions;
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Runtime.CompilerServices;
    
    public class FindSearchQueryBuilder : ISearchQueryBuilder
    {
        private static readonly Dictionary<string, Language> _providerLanguages = Language.GetAll().ToDictionary<Language, string>(l => l.get_FieldSuffix(), LanguageComparer.Instance);
        
        public FindSearchQueryBuilder(IClient client, ISearchCriteria criteria)
        {
            ITypeSearch<FindDocument> search;
            ProviderClient client2 = client as ProviderClient;
            if (client2 == null)
            {
                throw new InvalidOperationException("The Find search query builder only works with clients created by the provider.");
            }
            ISearchConfiguration providerConfiguration = client2.ProviderConfiguration;
            Language language = null;
            if (!criteria.get_IgnoreFilterOnLanguage() && _providerLanguages.TryGetValue(criteria.get_Locale(), out language))
            {
                search = client2.Search<FindDocument>(language);
            }
            else
            {
                search = client2.Search<FindDocument>();
            }
            CatalogEntrySearchCriteria criteria2 = criteria as CatalogEntrySearchCriteria;
            if (criteria2 != null)
            {
                if (criteria.get_IgnoreFilterOnLanguage())
                {
                    search = search.ForDefaultFields(criteria2.get_SearchPhrase(), string.Empty);
                }
                else
                {
                    search = search.ForDefaultFields(criteria2.get_SearchPhrase(), criteria.get_Locale());
                    string str = string.IsNullOrEmpty(language.get_FieldSuffix()) ? ContentLanguage.get_PreferredCulture().Name : language.get_FieldSuffix();
                    search = search.FilterLanguages(str);
                }
                if ((DateTime.MinValue < criteria2.get_StartDate()) && (criteria2.get_EndDate() < DateTime.MaxValue))
                {
                    search = search.FilterDates(criteria2.get_StartDate(), criteria2.get_EndDate(), criteria2.get_IncludePreorderEntry());
                }
                search = search.FilterCatalogs(this.ToStringEnumerable(criteria2.get_CatalogNames())).FilterCatalogNodes(this.GetNodes(criteria2)).FilterOutlines(this.GetOutlines(criteria2)).FilterMetaClasses(this.ToStringEnumerable(criteria2.get_SearchIndex())).FilterCatalogEntryTypes(this.ToStringEnumerable(criteria2.get_ClassTypes()));
                if (!criteria2.get_IncludeInactive())
                {
                    search = search.FilterInactiveCatalogEntries();
                }
                if (criteria2.get_MarketId() != MarketId.Empty)
                {
                    search = search.FilterCatalogEntryMarket(criteria2.get_MarketId());
                }
            }
            search = search.AddActiveFilters(criteria).AddFacets(criteria).OrderBy(criteria);
            if (criteria.get_StartingRecord() > 0)
            {
                search = SearchExtensions.Skip<FindDocument>(search, criteria.get_StartingRecord());
            }
            if (criteria.get_RecordsToRetrieve() > 0)
            {
                search = SearchExtensions.Take<FindDocument>(search, criteria.get_RecordsToRetrieve());
            }
            this.Search = search;
        }


Problem seems to be that EPiServer.Find.GetAll() returns languages with two letters like for example: 'no' among 33 or so others
CMS is configured to use only 'nb-NO'

so in EPiServer.Commerce.FindSearchProvider.FindSearchQueryBuilder(see image below):

  • in line 18 there is static list that fetches langauges from EPiServer.Find.GetAll()
  • it tries to find nb-NO in it in line 30 and fails to do so
  • and as language is null then previous exception is thrown in line 48

decompiled FindSearchQueryBuilder

#145705
Edited, Mar 10, 2016 12:29
Vote:
 

As a temporary workaround I have modified:

  • Apps\Catalog\CatalogEntrySearch.ascx
<%@ Import Namespace="System.Reflection" %>
<%@ Import Namespace="EPiServer.Find" %>
<script runat="server">

    protected void Page_Load(object sender, EventArgs e)
    {
        base.Page_Load(sender, e);

        var type = typeof(Language);
        var field = type.GetField("_allLanguages", BindingFlags.Static | BindingFlags.NonPublic);
        if (field == null)
        {
            throw new NotImplementedException("_allLanguages must not be null");
        }
        var allLanguages = Language.GetAll().ToList();
        if (allLanguages.All(x => x.FieldSuffix != "nb-NO"))
        {
            allLanguages.Add(new Language("Norwegian", "norwegian", "nb-NO", "norwegian", "norwegian_synonym"));

            field.SetValue(null, allLanguages);
        }
    }

</script>

to add 'nb-NO' to EPiServer.Find.Language class using reflection and that solves problem and epi.find search works in manager,

question is am I doing something wrong or this is bug of either or multiple ones of these:

  • EPiServer.CommerceManager
  • EPiServer.Find
  • EPiServer.Commerce.FindSearchProvider
#145706
Mar 10, 2016 12:37
Vote:
 
<p>I believe you can do it like this:</p> <p>- Enable nosrk (no) in CMS Admin</p> <p>- Make it the default language for Commerce Manager (Administration/System Settings/Common Settings)</p> <p>Otherwise edit&nbsp;<span>CatalogEntrySearch.ascx to make sure the ListLanguages.SelectedValue = "no" by default&nbsp;</span></p> <p><span>I'll file a bug for this to see if we can come up with a solution.</span></p> <p><span>/Q</span></p> <p><span></span></p> <p></p> <p></p>
#145721
Mar 10, 2016 14:27
Vote:
 

But all our content and products are under 'nb-NO' and we dont want to migrate that(probably would not be easy as well)

So yes, please fix it.

#145723
Mar 10, 2016 14:30
Vote:
 

I'm not a Find expert, but from what I understand when you come to Find, it'll index by main language only, not culture specific. So even your language is nb-NO, it will index as "no" - so I don't think it really makes sense when you search here.

Regards,

/Q 

#145724
Edited, Mar 10, 2016 14:41
Vote:
 

No, it indexes 'nb-NO' and not 'no'

Becasue even without this fix, search from CMS Commerce UI works(//<site>/cms/Commerce/Catalog), its done correct there.

And indexed FindDocument items have:

 "Languages": [
        "nb-no"
    ],

most likely because commerce data is saved as 'nb-NO'

#145725
Edited, Mar 10, 2016 14:47
Vote:
 
<p>It even uses CMS defined languages to filter on, example:</p> <p><img src="http://s24.postimg.org/jwg3b7eud/Find_Search_Provider3.jpg" width="798" alt="" height="258" /></p> <p></p> <p>and if your CMS uses 'no' you are fine no hacks needed, but if it uses 'nb-NO' it fails with:&nbsp;NullReferenceException</p> <p>Unless some hacking is done</p>
#145727
Mar 10, 2016 14:54
Vote:
 
<p>The Languages field in FindDocument is passed with languages in the CatalogLanguage when the entry is indexed. It's just another field, not really a "system" field which Find cares about.</p> <p>It worked in the Catalog UI because the locale is set&nbsp;<span>ContentLanguage</span><span>.</span>PreferredCulture<span>.</span>Name, which I suppose to be something like en or no, not nb-NO.</p> <p>Regards,</p> <p>/Q</p>
#145728
Mar 10, 2016 14:56
Vote:
 

It works in Catalog UI from any locale, becasue it(locale) is not sent over wire to epi.find.

CatalogUI does not specify language at all, while manager provides that feature and fails with 'nb-NO' unless EPiServer.Find.GetAll() is forced to return 'nb-NO'

CatalogUI example:

POST http://es-eu-dev-api01.episerver.net/xxxx/YYYY/_search HTTP/1.1
Content-Type: application/json
User-Agent: EPiServer-Find-NET-API/11.1.1.4013
Host: es-eu-dev-api01.episerver.net
Content-Length: 999
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

{
   "size":10,
   "query":{
      "filtered":{
         "query":{
            "filtered":{
               "query":{
                  "query_string":{
                     "query":"77777777"
                  }
               },
               "filter":{
                  "and":[
                     {
                        "or":[
                           {
                              "range":{
                                 "StartDate$$date":{
                                    "from":"0001-01-01T00:00:00Z",
                                    "to":"9999-12-31T21:59:59.9999999Z",
                                    "include_lower":true,
                                    "include_upper":false
                                 }
                              }
                           },
                           {
                              "term":{
                                 "StartDate$$date":"9999-12-31T21:59:59.9999999Z"
                              }
                           },
                           {
                              "and":[
                                 {
                                    "term":{
                                       "AllowPreorder$$bool":true
                                    }
                                 },
                                 {
                                    "or":[
                                       {
                                          "range":{
                                             "PreorderAvailableDate$$date":{
                                                "from":"0001-01-01T00:00:00Z",
                                                "to":"9999-12-31T21:59:59.9999999Z",
                                                "include_lower":true,
                                                "include_upper":false
                                             }
                                          }
                                       },
                                       {
                                          "term":{
                                             "PreorderAvailableDate$$date":"9999-12-31T21:59:59.9999999Z"
                                          }
                                       }
                                    ]
                                 }
                              ]
                           }
                        ]
                     },
                     {
                        "or":[
                           {
                              "range":{
                                 "EndDate$$date":{
                                    "from":"0001-01-01T00:00:00Z",
                                    "to":"9999-12-31T21:59:59.9999999Z",
                                    "include_lower":false,
                                    "include_upper":true
                                 }
                              }
                           },
                           {
                              "term":{
                                 "EndDate$$date":"0001-01-01T00:00:00Z"
                              }
                           }
                        ]
                     },
                     {
                        "or":[
                           {
                              "term":{
                                 "Catalogs.lowercase":"nettbutikk"
                              }
                           },
                           {
                              "term":{
                                 "Catalogs.lowercase":"produktkatalog"
                              }
                           }
                        ]
                     }
                  ]
               }
            }
         },
         "filter":{
            "term":{
               "___types":"EPiServer.Commerce.FindSearchProvider.FindDocument"
            }
         }
      }
   }
}

manager example:

POST http://es-eu-dev-api01.episerver.net/xxxx/YYYY/_search HTTP/1.1
Content-Type: application/json
User-Agent: EPiServer-Find-NET-API/11.1.1.4013
Host: es-eu-dev-api01.episerver.net
Content-Length: 956
Expect: 100-continue
Accept-Encoding: gzip, deflate

{
   "size":20,
   "query":{
      "filtered":{
         "query":{
            "constant_score":{
               "filter":{
                  "and":[
                     {
                        "term":{
                           "Languages.lowercase":"nb-no"
                        }
                     },
                     {
                        "or":[
                           {
                              "range":{
                                 "StartDate$$date":{
                                    "from":"0001-01-01T00:00:00Z",
                                    "to":"9999-12-31T21:59:59.9999999Z",
                                    "include_lower":true,
                                    "include_upper":false
                                 }
                              }
                           },
                           {
                              "term":{
                                 "StartDate$$date":"9999-12-31T21:59:59.9999999Z"
                              }
                           },
                           {
                              "and":[
                                 {
                                    "term":{
                                       "AllowPreorder$$bool":true
                                    }
                                 },
                                 {
                                    "or":[
                                       {
                                          "range":{
                                             "PreorderAvailableDate$$date":{
                                                "from":"0001-01-01T00:00:00Z",
                                                "to":"9999-12-31T21:59:59.9999999Z",
                                                "include_lower":true,
                                                "include_upper":false
                                             }
                                          }
                                       },
                                       {
                                          "term":{
                                             "PreorderAvailableDate$$date":"9999-12-31T21:59:59.9999999Z"
                                          }
                                       }
                                    ]
                                 }
                              ]
                           }
                        ]
                     },
                     {
                        "or":[
                           {
                              "range":{
                                 "EndDate$$date":{
                                    "from":"0001-01-01T00:00:00Z",
                                    "to":"9999-12-31T21:59:59.9999999Z",
                                    "include_lower":false,
                                    "include_upper":true
                                 }
                              }
                           },
                           {
                              "term":{
                                 "EndDate$$date":"0001-01-01T00:00:00Z"
                              }
                           }
                        ]
                     },
                     {
                        "term":{
                           "CatalogEntryCode$$string.lowercase":"77777777"
                        }
                     }
                  ]
               }
            }
         },
         "filter":{
            "term":{
               "___types":"EPiServer.Commerce.FindSearchProvider.FindDocument"
            }
         }
      }
   }
}
#145729
Edited, Mar 10, 2016 15:08
Vote:
 
<p>OK so I checked the code and for Catalog UI IgnoreFilterOnLanguage is set to true, so it'll ignore the Locale.</p> <p>And checked the FindSearchProvider again (aka FindDocument), I realized that FindSearchProvider uses Find in, uhm, "different" way.</p> <p>So my workaround does not work - ignore it.&nbsp;</p> <p>We'll work on a proper fix.</p> <p>/Q</p> <p></p>
#145733
Mar 10, 2016 15:46
Vote:
 

Quan Mai, thanks for assistance!

What is estimate for proper fix?

#145750
Mar 11, 2016 7:22
Vote:
 

As usual, I can guess it is 3-4 weeks away. We'll work on it as soon as we can but it will still have to go through code review and QA tests. Just don't take my words as promises.

/Q

#145751
Mar 11, 2016 7:44
Vote:
 

Hi,

The bug is now fixed and will be delivered in FindCommerce 9.5.1. You can track it here: http://world.episerver.com/support/Bug-list/bug/COM-1222

Regards.

/Q

#147039
Apr 05, 2016 5:33
Vote:
 

Dont know about FindCommerce 9.5.1 as we are not using it,

but it seems to be fixed in EPiServer.Commerce.FindSearchProvider.8.12.1

#147043
Apr 05, 2016 9:14
Vote:
 
<p>Many thanks to Quan Mai, as always its productive way how to resolve EPiServer issues</p>
#147044
Apr 05, 2016 9:19
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.