1

I have Sitecore 9.3 SXA with Azure search in our application. We are trying to create a custom SXA search token to filter upcoming events starting from the current date. In the code am trying to pass the date range as [2020-11-30T00:00:00.000Z TO *] in SearchStringModel. It is working fine in my local with Solr search when testing the code on dev with Azure search. Below is the error from the Console for the SXA search service, log details, and code implementation for reference.

**Error:** Field 'eventdate_dt' with value '[2020-11-30T00:00:00.000Z TO *]' of type 'System.String' cannot be converted to type 'System.DateTimeOffset' declared for the field in the schema.

**Log**
Exception: System.NotSupportedException
Message: Field 'eventdate_dt' with value '[2020-11-30T00:00:00.000Z TO *]' of type 'System.String' cannot be converted to type 'System.DateTimeOffset' declared for the field in the schema.
Source: Sitecore.XA.Foundation.Search.Providers.Azure
   at Sitecore.XA.Foundation.Search.Providers.Azure.CloudIndexFieldStorageValueFormatter.FormatValueForIndexStorage(Object value, String fieldName)
   at Sitecore.ContentSearch.Azure.Query.CloudQueryMapper.HandleWildcardMatch(WildcardMatchNode node)
   at Sitecore.ContentSearch.Azure.Query.CloudQueryMapper.HandleAnd(AndNode node, CloudQueryMapperState mappingState)
   at Sitecore.ContentSearch.Azure.Query.CloudQueryMapper.HandleWhere(WhereNode node, CloudQueryMapperState mappingState)
   at Sitecore.ContentSearch.Azure.Query.CloudQueryMapper.HandleWhere(WhereNode node, CloudQueryMapperState mappingState)
   at Sitecore.ContentSearch.Azure.Query.CloudQueryMapper.HandleWhere(WhereNode node, CloudQueryMapperState mappingState)
   at Sitecore.ContentSearch.Azure.Query.CloudQueryMapper.MapQuery(IndexQuery query)
   at Sitecore.XA.Foundation.Search.Spatial.GenericQueryable`2.GetQuery(Expression expression)
   at Sitecore.ContentSearch.Linq.Parsing.GenericQueryable`2.Execute[TResult](Expression expression)
   at Sitecore.XA.Feature.Search.Controllers.SearchController.GetResults(QueryModel model)   

Nested Exception

Exception: System.FormatException
Message: String was not recognized as a valid DateTime.
Source: mscorlib
   at System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, TimeSpan& offset)
   at System.DateTimeOffset.Parse(String input, IFormatProvider formatProvider, DateTimeStyles styles)
   at Sitecore.XA.Foundation.Search.Providers.Azure.CloudIndexFieldStorageValueFormatter.TryConvertToPrimitiveType(Object value, Type expectedType, Object& result)
   at Sitecore.XA.Foundation.Search.Providers.Azure.CloudIndexFieldStorageValueFormatter.ConvertToType(Object value, Type expectedType, ITypeDescriptorContext context)
   at Sitecore.XA.Foundation.Search.Providers.Azure.CloudIndexFieldStorageValueFormatter.FormatValueForIndexStorage(Object value, String fieldName)

Code

public class ExcludeItemsWithPreviousDates : ResolveSearchQueryTokensProcessor
{
    protected string TokenPart { get; } = "ExcludeItemWithPreviousDateInDateField";

    [SxaTokenKey]
    protected override string TokenKey => FormattableString.Invariant(FormattableStringFactory.Create("{0}|FieldName", (object)this.TokenPart));
 
    public override void Process(ResolveSearchQueryTokensEventArgs args)
    {
        if (args.ContextItem == null || args.ContextItem.ID.IsNull)
            return;

        try 
        {  
           for (var index = 0; index < args.Models.Count; ++index)
           {  
                var model = args.Models[index];
                Log.Info($"SXA_Token model:{model.Value}", "SXA_Token");
                if (model.Type.Equals("sxa", StringComparison.OrdinalIgnoreCase) && ContainsToken(model))
                {
                    string fieldName = model.Value.Replace(TokenPart, string.Empty).TrimStart('|');
                   
                    var dateField = args.ContextItem.Fields[fieldName];
                    Log.Info($"SXA_Token field:{dateField}", "SXA_Token");
                    if (dateField != null)
                    {
                        Log.Info($"SXA_Token model value:{args.Models[index].Value}", "SXA_Token");
                        args.Models.Insert(index, this.BuildModel(fieldName));
                        args.Models.Remove(model);
                    }
                    Log.Info($"SXA_Token model removing: {model.Value}", "SXA_Token");
                }
            }
        }
        catch(Exception e)
        {
            Log.Error($"SXA_Token Exceptio:{e.Message}", "SXA_Token");
        }            
    }

    private SearchStringModel BuildModel(string fieldName)
    {
        Log.Info($"SXA_Token customSearchModel: {new SearchStringModel("custom", FormattableString.Invariant(FormattableStringFactory.Create("{0}|{1}", (object)fieldName.ToLowerInvariant(), $"[{DateTime.Today.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'")} TO *]")))}", "SXA_Token");
        return new SearchStringModel("custom", FormattableString.Invariant(FormattableStringFactory.Create("{0}|{1}", (object)fieldName.ToLowerInvariant(), (object)$"[{DateTime.Today.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'")} TO *]" )))
        {
            Operation = "must"
        };     
    }

    protected override bool ContainsToken(SearchStringModel m)
    {
        return Regex.Match(m.Value, FormattableString.Invariant(FormattableStringFactory.Create("{0}\\|[a-zA-Z ]*", (object)this.TokenPart))).Success;
    }
}
2
  • The issue is not with your custom token or model - it's the mapping of the fields that is not working. Can you show the class that is used for the query?
    – Gatogordo
    Nov 30 '20 at 14:19
  • It just might be related to a bug I had in a previous version - not sure if that it fixed already sitecore.stackexchange.com/a/14520/237
    – Gatogordo
    Nov 30 '20 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.