Sitecore Как устранить ошибку Неверное приведение из "System.String" к "Sitecore.Data.ID" в Sitecore Search
Я использую API поиска по сайту, но получаю исключение 'Exception Details: System.InvalidCastException: Invalid cast from 'System.String' to 'Sitecore.Data.ID'.'
На этой линии: foreach (var result in query)
, Я использую следующий код:
using (var context = ContentSearchManager.GetIndex("my_text_index").CreateSearchContext())
{
IQueryable<Person> query = context.GetQueryable<Person>().Where(p=> p.Firstname.Equals("John"));
foreach(result in query) // I am getting the exception here on this line.
{
lbltest.Text = result.Name;
}
}
Это класс "Person
"
public class Person : SearchResultItem
{
[IndexField("firstname_t")]
public string Firstname { get; set; }
[IndexField("surname_t")]
public string Surname { get; set; }
}
Это трассировка стека:
[InvalidCastException: Invalid cast from 'System.String' to 'Sitecore.Data.ID'.]
System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) +14116726
System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +14116814
Sitecore.ContentSearch.Converters.IndexFieldStorageValueFormatter.ReadFromIndexStorage(Object indexValue, Type destinationType) +609
[InvalidCastException: Could not convert value of type System.String to destination type Sitecore.Data.ID: Invalid cast from 'System.String' to 'Sitecore.Data.ID'.]
Sitecore.ContentSearch.Converters.IndexFieldStorageValueFormatter.ReadFromIndexStorage(Object indexValue, Type destinationType) +869
Sitecore.ContentSearch.DocumentTypeMapInfo.SetProperty(Object target, String propertyName, String documentFieldName, Object value) +172
[InvalidCastException: Could not map index document field to property "ItemId" on type Starco.ISK.Website.Search.PersonSearchItem : Could not convert value of type System.String to destination type Sitecore.Data.ID: Invalid cast from 'System.String' to 'Sitecore.Data.ID'.]
Sitecore.ContentSearch.DocumentTypeMapInfo.SetProperty(Object target, String propertyName, String documentFieldName, Object value) +360
Sitecore.ContentSearch.DefaultDocumentMapper`1.MapFieldValuesToType(IDictionary`2 fieldValues, TElement result, DocumentTypeMapInfo documentTypeMapInfo) +792
Sitecore.ContentSearch.LuceneProvider.DefaultLuceneDocumentTypeMapper.ReadDocumentFields(Document document, IEnumerable`1 fieldNames, DocumentTypeMapInfo documentTypeMapInfo, IEnumerable`1 virtualFieldProcessors, TElement result) +1249
Sitecore.ContentSearch.DefaultDocumentMapper`1.MapToType(TDocument document, SelectMethod selectMethod, IEnumerable`1 virtualFieldProcessors, SearchSecurityOptions securityOptions) +283
Sitecore.ContentSearch.LuceneProvider.<GetSearchResults>d__8.MoveNext() +1577
Starco.ISK.Website.Search.Output.Page_Load(Object sender, EventArgs e) in e:\IIS Data\Starco_intra.starco.com\Website\Search\Output.ascx.cs:76
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Control.LoadRecursive() +190
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3178
Файл конфигурации для индекса:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<contentSearch>
<configuration type="Sitecore.ContentSearch.LuceneProvider.LuceneSearchConfiguration, Sitecore.ContentSearch.LuceneProvider">
<indexes hint="list:AddIndex">
<index id="my_text_Index" type="Sitecore.ContentSearch.LuceneProvider.LuceneIndex, Sitecore.ContentSearch.LuceneProvider">
<param desc="name">$(id)</param>
<param desc="folder">$(id)</param>
<param desc="propertyStore" ref="contentSearch/databasePropertyStore" param1="$(id)" />
<Configuration ref="profileSearch/configuration" />
<strategies hint="list:AddStrategy">
<strategy ref="contentSearch/indexUpdateStrategies/onPublishEndAsync" />
</strategies>
<commitPolicyExecutor type="Sitecore.ContentSearch.CommitPolicyExecutor, Sitecore.ContentSearch">
<policies hint="list:AddCommitPolicy">
<policy type="Sitecore.ContentSearch.TimeIntervalCommitPolicy, Sitecore.ContentSearch" />
</policies>
</commitPolicyExecutor>
<locations hint="list:AddCrawler">
<crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
<Database>master</Database>
<Root>/sitecore/content/Intranet</Root>
</crawler>
</locations>
</index>
</indexes>
</configuration>
</contentSearch>
</sitecore>
</configuration>
Ниже приведена страница showconfig.aspx sitecore/admin/showconfig.aspx:
<indexFieldStorageValueFormatter type="Sitecore.ContentSearch.LuceneProvider.Converters.LuceneIndexFieldStorageValueFormatter, Sitecore.ContentSearch.LuceneProvider">
<converters hint="raw:AddConverter">
<converter handlesType="System.Guid" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldGuidValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="Sitecore.Data.ID, Sitecore.Kernel" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldIDValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="Sitecore.Data.ShortID, Sitecore.Kernel" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldShortIDValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="System.Boolean" typeConverter="Sitecore.ContentSearch.LuceneProvider.Converters.IndexFieldBooleanValueConverter, Sitecore.ContentSearch.LuceneProvider"/>
<converter handlesType="System.DateTime" typeConverter="Sitecore.ContentSearch.LuceneProvider.Converters.IndexFieldDateTimeValueConverter, Sitecore.ContentSearch.LuceneProvider"/>
<converter handlesType="System.DateTimeOffset" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldDateTimeOffsetValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="System.TimeSpan" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldTimeSpanValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="Sitecore.ContentSearch.SitecoreItemId, Sitecore.ContentSearch" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldSitecoreItemIDValueConvertor, Sitecore.ContentSearch">
<param type="Sitecore.ContentSearch.Converters.IndexFieldIDValueConverter, Sitecore.ContentSearch"/>
</converter>
<converter handlesType="Sitecore.ContentSearch.SitecoreItemUniqueId, Sitecore.ContentSearch" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldSitecoreItemUniqueIDValueConverter, Sitecore.ContentSearch">
<param type="Sitecore.ContentSearch.Converters.IndexFieldItemUriValueConverter, Sitecore.ContentSearch"/>
</converter>
<converter handlesType="Sitecore.Data.ItemUri, Sitecore.Kernel" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldItemUriValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="Sitecore.Globalization.Language, Sitecore.Kernel" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldLanguageValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="System.Globalization.CultureInfo" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldCultureInfoValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="Sitecore.Data.Version, Sitecore.Kernel" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldVersionValueConverter, Sitecore.ContentSearch"/>
<converter handlesType="Sitecore.Data.Database, Sitecore.Kernel" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldDatabaseValueConverter, Sitecore.ContentSearch"/>
</converters>
</indexFieldStorageValueFormatter>
4 ответа
Я думаю, что конфигурация не работает.
IndexFieldStorageValueFormatter
не может найти подходящий TypeConverter и возвращается к Convert.ChangeType. Но класс ID не имеет операторов преобразования для строк, поэтому преобразование завершается неудачно.
Он должен был найти подходящий TypeConverter. Он собран из конфигурации, по умолчанию в Sitecore.ContentSearch.Lucene.DefaultIndexConfiguration
, Это должно иметь indexFieldStorageValueFormatter
раздел, где эта строка особенно полезна в этой ситуации:
<converter handlesType="Sitecore.Data.ID, Sitecore.Kernel" typeConverter="Sitecore.ContentSearch.Converters.IndexFieldIDValueConverter, Sitecore.ContentSearch" />
Убедитесь, что конфигурация contentsearch правильная и что ваш пользовательский my_text_index
не отменяет эту часть.
Вы можете использовать dotPeek для генерации файла pdb и отладки IndexFieldStorageValueFormatter
но я думаю, вы придете к такому же выводу, что у него нет конвертера для этого типа.
Попробуйте обновить следующим образом:
using (var context = ContentSearchManager.GetIndex("my_text_index").CreateSearchContext())
{
IQueryable<Person> query = context.GetQueryable<Person>().Where(p=> p.Firstname == "John");
SearchResults<Person> results = query.GetResults();
foreach(result in results) // I am getting the exception here on this line.
{
lbltest.Text = result.Name;
}
}
Проблема возникает в базовом классе SearchResultItem
при преобразовании строки в индексе в guid Sitecore.
Это будет указывать на некоторые мошеннические данные в индексе для поля itemid. Первое, что нужно сделать, - это зайти в файл Search.log, чтобы проверить фактический выполняемый запрос, а затем использовать Luke для запуска запроса, чтобы увидеть результаты.
Вероятно, что запись в индексе имеет поле (__group), которое не в формате для Sitecore Guid.
Обычно это означает, что в вашем имуществе отсутствует атрибут преобразования. Но ни один из них не является идентификатором.
Похоже, у вас есть IndexField
атрибуты установлены неправильно, хотя. Вам не нужно добавлять суффикс типа в конце. API Sitecore сделает это за вас.
Так что поменяйте Person
класс для:
public class Person : SearchResultItem
{
[IndexField("firstname")]
public string Firstname { get; set; }
[IndexField("surname")]
public string Surname { get; set; }
}
Также убедитесь, что поля не являются идентификаторами полей в CMS.