Upgrade auf Version 1.1 des Azure Search .NET SDK
Wenn Sie die Version „1.0.2-preview“ oder eine frühere Version des Azure Search .NET SDK verwenden, unterstützt dieser Artikel Sie beim Upgrade Ihrer Anwendung auf Version 1.1.
Eine allgemeinere exemplarische Vorgehensweise für das SDK sowie Beispiele finden Sie unter Verwenden von Azure Search aus einer .NET-Anwendung.
Hinweis
Nach einem Upgrade auf Version 1.1, oder wenn Sie bereits eine Version zwischen 1.1 und 2.0-Preview inklusive verwenden, sollten Sie ein Upgrade auf Version 3 vornehmen. Anweisungen finden Sie unter Upgrade auf Version 3 des Azure Search .NET SDK.
Aktualisieren Sie zunächst die NuGet-Referenz für Microsoft.Azure.Search
, indem Sie entweder die NuGet-Paket-Manager-Konsole verwenden oder mit der rechten Maustaste auf die Projektverweise klicken und in Visual Studio „NuGet-Pakete verwalten...“ auswählen.
Nachdem NuGet die neuen Pakete und deren Abhängigkeiten heruntergeladen hat, erstellen Sie Ihr Projekt neu.
Wenn Sie zuvor die Versionen 1.0.0-preview, 1.0.1-preview oder 1.0.2-preview verwendet haben, sollte die Erstellung erfolgreich sein, und Sie können direkt anfangen!
Wenn Sie zuvor Version 0.13.0-preview oder älter verwendet haben, sollten Erstellungsfehler ähnlich den folgenden angezeigt werden:
Program.cs(137,56,137,62): error CS0117: 'Microsoft.Azure.Search.Models.IndexBatch' does not contain a definition for 'Create'
Program.cs(137,99,137,105): error CS0117: 'Microsoft.Azure.Search.Models.IndexAction' does not contain a definition for 'Create'
Program.cs(146,41,146,54): error CS1061: 'Microsoft.Azure.Search.IndexBatchException' does not contain a definition for 'IndexResponse' and no extension method 'IndexResponse' accepting a first argument of type 'Microsoft.Azure.Search.IndexBatchException' could be found (are you missing a using directive or an assembly reference?)
Program.cs(163,13,163,42): error CS0246: The type or namespace name 'DocumentSearchResponse' could not be found (are you missing a using directive or an assembly reference?)
Der nächste Schritt besteht darin, die Buildfehler einzeln zu beheben. Für die meisten müssen einige Klassen- und Methodennamen geändert werden, die im SDK umbenannt wurden. Liste mit wichtigen Änderungen in Version 1.1 enthält eine Liste mit diesen Namensänderungen.
Wenn Sie benutzerdefinierte Klassen zum Modellieren von Dokumenten verwenden und diese Klassen Eigenschaften mit primitiven Datentypen umfassen, die keine NULL-Werte zulassen (z.B. int
oder bool
in C#), sollten Sie eine Programmfehlerbehebung in der Version 1.1 des SDK kennen. Weitere Details finden Sie unter Fehlerbehebungen in Version 1.1.
Sobald Sie alle Buildfehler behoben haben, können Sie Änderungen an Ihrer Anwendung vornehmen, um nach Bedarf die neue Funktionalität zu nutzen.
Liste mit wichtigen Änderungen in Version 1.1
Die folgende Liste ist nach der Wahrscheinlichkeit sortiert, dass die Änderung sich auf den Anwendungscode auswirkt.
Änderungen an IndexBatch und IndexAction
IndexBatch.Create
wurde in IndexBatch.New
umbenannt und umfasst kein params
-Argument mehr. Sie können IndexBatch.New
für Batches verwenden, in denen verschiedene Typen von Aktionen (Zusammenführen, Löschen usw.) kombiniert werden. Darüber hinaus stehen neue statische Methoden zum Erstellen von Batches zur Verfügung, in denen alle Aktionen identisch sind: Delete
, Merge
, MergeOrUpload
und Upload
.
IndexAction
verfügt nicht länger über öffentliche Konstruktoren, und die zugehörigen Eigenschaften sind jetzt unveränderlich. Sie sollten die neuen statischen Methoden zum Erstellen von Aktionen für verschiedene Zwecke verwenden: Delete
, Merge
, MergeOrUpload
und Upload
.
IndexAction.Create
wurde entfernt. Wenn Sie die Überladung verwendet haben, die nur ein Dokument akzeptiert, müssen Sie stattdessen Upload
verwenden.
Beispiel
Angenommen, Sie verwenden folgenden Code:
var batch = IndexBatch.Create(documents.Select(doc => IndexAction.Create(doc)));
indexClient.Documents.Index(batch);
Zum Beheben von Buildfehlern können Sie diesen Code folgendermaßen ändern:
var batch = IndexBatch.New(documents.Select(doc => IndexAction.Upload(doc)));
indexClient.Documents.Index(batch);
Wenn Sie möchten, können Sie ihn weiter vereinfachen:
var batch = IndexBatch.Upload(documents);
indexClient.Documents.Index(batch);
Änderungen an IndexBatchException
Die IndexBatchException.IndexResponse
-Eigenschaft wurde umbenannt in IndexingResults
, und ihr Typ ist jetzt IList<IndexingResult>
.
Beispiel
Angenommen, Sie verwenden folgenden Code:
catch (IndexBatchException e)
{
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexResponse.Results.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Zum Beheben von Buildfehlern können Sie diesen Code folgendermaßen ändern:
catch (IndexBatchException e)
{
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Änderungen an der Vorgangsmethode
Jeder Vorgang im Azure Search .NET SDK wird als eine Reihe von Methodenüberladungen für synchrone und asynchrone Aufrufer verfügbar gemacht. Die Signaturen und die Faktorisierung dieser Methodenüberladungen wurden in der Version 1.1 geändert.
Durch den Vorgang „Indexstatistiken abrufen“ in älteren Versionen des SDK wurden beispielsweise folgende Signaturen verfügbar gemacht:
In IIndexOperations
:
// Asynchronous operation with all parameters
Task<IndexGetStatisticsResponse> GetStatisticsAsync(
string indexName,
CancellationToken cancellationToken);
In IndexOperationsExtensions
:
// Asynchronous operation with only required parameters
public static Task<IndexGetStatisticsResponse> GetStatisticsAsync(
this IIndexOperations operations,
string indexName);
// Synchronous operation with only required parameters
public static IndexGetStatisticsResponse GetStatistics(
this IIndexOperations operations,
string indexName);
Die Methodensignaturen für denselben Vorgang sehen in Version 1.1 folgendermaßen aus:
In IIndexesOperations
:
// Asynchronous operation with lower-level HTTP features exposed
Task<AzureOperationResponse<IndexGetStatisticsResult>> GetStatisticsWithHttpMessagesAsync(
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
Dictionary<string, List<string>> customHeaders = null,
CancellationToken cancellationToken = default(CancellationToken));
In IndexesOperationsExtensions
:
// Simplified asynchronous operation
public static Task<IndexGetStatisticsResult> GetStatisticsAsync(
this IIndexesOperations operations,
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
CancellationToken cancellationToken = default(CancellationToken));
// Simplified synchronous operation
public static IndexGetStatisticsResult GetStatistics(
this IIndexesOperations operations,
string indexName,
SearchRequestOptions searchRequestOptions = default(SearchRequestOptions));
Ab Version 1.1 werden Vorgangsmethoden in Azure Search .NET SDK anders organisiert:
- Optionale Parameter werden jetzt als Standardparameter statt als zusätzliche Methodenüberladungen modelliert. Dadurch verringert sich die Anzahl an Methodenüberladungen zum Teil erheblich.
- Bei den Erweiterungsmethoden werden jetzt viele irrelevante HTTP-Details für den Aufrufer ausgeblendet. Ältere Versionen des SDK gaben zum Beispiel ein Antwortobjekt mit einem HTTP-Statuscode zurück, den Sie häufig nicht überprüfen mussten, weil Vorgangsmethoden für jeden Statuscode, der einen Fehler angibt,
CloudException
auslösen. Die neuen Erweiterungsmethoden geben nur Modellobjekte zurück, sodass Sie sie nicht extra in Ihrem Code entpacken müssen. - Umgekehrt machen die Kernschnittstellen jetzt Methoden verfügbar, die Ihnen mehr Steuerungsmöglichkeiten auf der HTTP-Ebene ermöglichen, wenn Sie sie benötigen. Sie können nun benutzerdefinierte HTTP-Header in Anforderungen übergeben, und der neue
AzureOperationResponse<T>
-Rückgabetyp bietet Ihnen direkten Zugriff auf die ElementeHttpRequestMessage
undHttpResponseMessage
für den Vorgang.AzureOperationResponse
wird imMicrosoft.Rest.Azure
-Namespace definiert und ersetztHyak.Common.OperationResponse
.
ScoringParameters-Änderungen
Eine neue Klasse mit dem Namen ScoringParameter
wurde im letzten SDK hinzugefügt, damit es einfacher wird, für Bewertungsprofile in einer Suchabfrage Parameter anzugeben. Bisher hatte die ScoringProfiles
-Eigenschaft der SearchParameters
-Klasse die Typisierung IList<string>
. Jetzt lautet die Typisierung IList<ScoringParameter>
.
Beispiel
Angenommen, Sie verwenden folgenden Code:
var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured"; // Use a scoring profile
sp.ScoringParameters = new[] { "featuredParam-featured", "mapCenterParam-" + lon + "," + lat };
Zum Beheben von Buildfehlern können Sie diesen Code folgendermaßen ändern:
var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured"; // Use a scoring profile
sp.ScoringParameters =
new[]
{
new ScoringParameter("featuredParam", new[] { "featured" }),
new ScoringParameter("mapCenterParam", GeographyPoint.Create(lat, lon))
};
Änderungen an Modellklassen
Aufgrund der Signaturänderungen, die unter Änderungen an der Vorgangsmethode beschrieben werden, wurden viele Klassen im Microsoft.Azure.Search.Models
-Namespace umbenannt oder entfernt. Beispiel:
-
IndexDefinitionResponse
wurde durchAzureOperationResponse<Index>
ersetzt. -
DocumentSearchResponse
wurde inDocumentSearchResult
umbenannt. -
IndexResult
wurde inIndexingResult
umbenannt. -
Documents.Count()
gibt jetztlong
mit der Dokumentanzahl anstelle vonDocumentCountResponse
zurück. -
IndexGetStatisticsResponse
wurde inIndexGetStatisticsResult
umbenannt. -
IndexListResponse
wurde inIndexListResult
umbenannt.
Zusammenfassung: Es wurden von OperationResponse
abgeleitete Klassen entfernt, die nur zum Umschließen eines Modellobjekts dienten. Bei den übrigen Klassen wurde das Suffix von Response
in Result
geändert.
Beispiel
Angenommen, Sie verwenden folgenden Code:
IndexerGetStatusResponse statusResponse = null;
try
{
statusResponse = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
return;
}
IndexerExecutionResult lastResult = statusResponse.ExecutionInfo.LastResult;
Zum Beheben von Buildfehlern können Sie diesen Code folgendermaßen ändern:
IndexerExecutionInfo status = null;
try
{
status = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
return;
}
IndexerExecutionResult lastResult = status.LastResult;
Antwortklassen und IEnumerable
Eine weitere Änderung, die sich auf Ihren Code auswirken kann, besteht darin, dass IEnumerable<T>
von Antwortklassen mit darin enthaltenen Auflistungen nicht mehr implementiert wird. Stattdessen können Sie direkt auf die Auflistungseigenschaft zugreifen. Angenommen, Sie verwenden folgenden Code:
DocumentSearchResponse<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response)
{
Console.WriteLine(result.Document);
}
Zum Beheben von Buildfehlern können Sie diesen Code folgendermaßen ändern:
DocumentSearchResult<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response.Results)
{
Console.WriteLine(result.Document);
}
Sonderfall für Webanwendungen
Wenn Sie eine Webanwendung verwenden, die DocumentSearchResponse
direkt serialisiert, um Suchergebnisse an den Browser zu senden, müssen Sie zum korrekten Serialisieren der Ergebnisse den Code ändern. Angenommen, Sie verwenden folgenden Code:
public ActionResult Search(string q = "")
{
// If blank search, assume they want to search everything
if (string.IsNullOrWhiteSpace(q))
q = "*";
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = _featuresSearch.Search(q)
};
}
Sie können ihn durch Abrufen der .Results
-Eigenschaft der Suchantwort ändern, um das Rendering der Suchergebnisse zu beheben:
public ActionResult Search(string q = "")
{
// If blank search, assume they want to search everything
if (string.IsNullOrWhiteSpace(q))
q = "*";
return new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = _featuresSearch.Search(q).Results
};
}
Nach solchen Fällen müssen Sie selbst in Ihrem Code suchen. Sie erhalten keine Warnung vom Compiler, weil JsonResult.Data
vom Typ object
ist.
Änderungen an CloudException
Die CloudException
-Klasse wurde vom Hyak.Common
-Namespace in den Microsoft.Rest.Azure
-Namespace verschoben. Darüber hinaus wurde die Error
-Eigenschaft in Body
umbenannt.
Änderungen an SearchServiceClient und SearchIndexClient
Der Typ der Credentials
-Eigenschaft wurde von SearchCredentials
in die Basisklasse ServiceClientCredentials
geändert. Wenn Sie auf die SearchCredentials
eines SearchIndexClient
oder SearchServiceClient
zugreifen müssen, ist es ratsam, die neue SearchCredentials
-Eigenschaft zu verwenden.
In älteren Versionen des SDK besaßen SearchServiceClient
und SearchIndexClient
Konstruktoren, die einen HttpClient
-Parameter akzeptierten. Diese wurden durch Konstruktoren ersetzt, die einen HttpClientHandler
und ein Array mit DelegatingHandler
-Objekten akzeptieren. Dies erleichtert die Installation benutzerdefinierter Ereignishandler für die Vorverarbeitung von HTTP-Anforderungen, falls erforderlich.
Schließlich wurden die Konstruktoren, die Uri
und SearchCredentials
akzeptierten, geändert. Angenommen, Sie verwenden folgenden Code:
var client =
new SearchServiceClient(
new SearchCredentials("abc123"),
new Uri("http://myservice.search.windows.net"));
Zum Beheben von Buildfehlern können Sie diesen Code folgendermaßen ändern:
var client =
new SearchServiceClient(
new Uri("http://myservice.search.windows.net"),
new SearchCredentials("abc123"));
Beachten Sie auch, dass der Typ des Parameters mit den Anmeldeinformationen in ServiceClientCredentials
geändert wurde. Dies wird sich wahrscheinlich nicht auf Ihren Code auswirken, weil SearchCredentials
von ServiceClientCredentials
abgeleitet wird.
Übergeben eine Anforderungs-ID
In früheren Versionen des SDK konnten Sie eine Anforderungs-ID für SearchServiceClient
oder SearchIndexClient
festlegen, die dann in jede Anforderung an die REST-API integriert wurde. Dies ist für die Behandlung von Problemen mit Ihrem Suchdienst nützlich, wenn Sie sich an den Support wenden müssen. Es ist jedoch noch nützlicher, eine eindeutige Anforderungs-ID für jeden Vorgang festzulegen, statt dieselbe ID für alle Vorgänge zu verwenden. Aus diesem Grund wurden die SetClientRequestId
-Methoden von SearchServiceClient
und SearchIndexClient
entfernt. Über den optionalen SearchRequestOptions
-Parameter können Sie stattdessen für jede Vorgangsmethode eine Anforderungs-ID übergeben.
Hinweis
In einer zukünftigen Version des SDK fügen wir einen neuen Mechanismus für die globale Festlegung einer Anforderungs-ID für die Clientobjekte hinzu. Dieser entspricht dem Ansatz, der von anderen Azure SDKs verwendet wird.
Beispiel
Angenommen, Sie verwenden folgenden Code:
client.SetClientRequestId(Guid.NewGuid());
...
long count = client.Documents.Count();
Zum Beheben von Buildfehlern können Sie diesen Code folgendermaßen ändern:
long count = client.Documents.Count(new SearchRequestOptions(requestId: Guid.NewGuid()));
Änderungen an Schnittstellennamen
Die Schnittstellennamen der Vorgangsgruppen wurden alle geändert und stimmen jetzt mit ihren entsprechenden Eigenschaftsnamen überein:
- Der Typ von
ISearchServiceClient.Indexes
wurde vonIIndexOperations
inIIndexesOperations
umbenannt. - Der Typ von
ISearchServiceClient.Indexers
wurde vonIIndexerOperations
inIIndexersOperations
umbenannt. - Der Typ von
ISearchServiceClient.DataSources
wurde vonIDataSourceOperations
inIDataSourcesOperations
umbenannt. - Der Typ von
ISearchIndexClient.Documents
wurde vonIDocumentOperations
inIDocumentsOperations
umbenannt.
Diese Änderung wird sich wahrscheinlich nicht auf Ihren Code auswirken, es sei denn, Sie haben Modelle dieser Schnittstellen zu Testzwecken erstellt.
Fehlerbehebungen in Version 1.1
In älteren Versionen des Azure Search .NET SDK lag ein Fehler in Bezug auf die Serialisierung benutzerdefinierter Modellklassen vor. Der Fehler konnte auftreten, wenn Sie eine benutzerdefinierte Modellklasse mit einer Eigenschaft erstellt haben, deren Typ keine NULL-Werte zuließ.
Schritte zum Reproduzieren
Erstellen Sie eine benutzerdefinierte Modellklasse mit einer Eigenschaft, deren Typ keine NULL-Werte zulässt. Fügen Sie z.B. eine öffentliche UnitCount
-Eigenschaft vom Typ int
anstelle von int?
hinzu.
Wenn Sie ein Dokument mit dem Standardwert dieses Typs indizieren (z.B. 0 für int
), lautet das Feld in Azure Search NULL. Wenn Sie anschließend nach diesem Dokument suchen, gibt der Search
-Aufruf JsonSerializationException
mit der Begründung aus, dass null
nicht in int
konvertiert werden kann.
Filter funktionieren möglicherweise auch nicht wie erwartet, da anstelle des gewünschten Werts NULL in den Index geschrieben wurde.
Details zur Korrektur
Wir haben dieses Problem in Version 1.1 des SDK behoben. Wenn Sie jetzt eine Modellklasse wie die folgende verwenden:
public class Model
{
public string Key { get; set; }
public int IntValue { get; set; }
}
und IntValue
auf 0 setzen, wird dieser Wert jetzt bei der Übertragung richtig als 0 serialisiert und auch als 0 im Index gespeichert. Auch der Roundtrip funktioniert erwartungsgemäß.
Bei diesem Ansatz gibt es ein potenzielles Problem, das Sie beachten sollten: Wenn Sie einen Modelltyp mit einer Eigenschaft verwenden, die keine NULL-Werte zulässt, müssen Sie garantieren , dass keine Dokumente im Index für das entsprechende Feld einen NULL-Wert enthalten. Weder das SDK noch die Azure Search-REST-API hilft Ihnen, dies durchzusetzen.
Dies ist nicht nur von hypothetischer Bedeutung: Stellen Sie sich ein Szenario vor, bei dem Sie ein neues Feld einem vorhandenen Index vom Typ Edm.Int32
hinzufügen. Nach dem Aktualisieren der Indexdefinition besitzen alle Dokumente einen NULL-Wert für das neue Feld (da in Azure Search alle Typen NULL-Werte zulassen). Wenn Sie für dieses Feld anschließend eine Modellklasse mit einer int
-Eigenschaft verwenden, die keine NULL-Werte zulässt, erhalten Sie beim Abrufen von Dokumenten folgendes JsonSerializationException
-Element:
Error converting value {null} to type 'System.Int32'. Path 'IntValue'.
Aus diesem Grund empfehlen wir als bewährte Methode in den Modellklassen die Verwendung von Typen, die NULL-Werte zulassen.
Weitere Informationen zu diesem Fehler und der entsprechenden Korrektur finden Sie auf GitHub.