Partager via


Mise à niveau vers le Kit de développement logiciel (SDK) .NET pour Recherche Azure version 1.1

Si vous utilisez la version 1.0.2-preview ou antérieure du sdk .NET recherche Azure , cet article vous aidera à mettre à niveau votre application pour utiliser la version 1.1.

Pour obtenir une procédure pas à pas plus générale du Kit de développement logiciel (SDK), consultez Guide pratique pour utiliser Recherche Azure à partir d’une application .NET.

Remarque

Une fois la mise à niveau vers la version 1.1 ou si vous utilisez déjà une version comprise entre 1.1 et 2.0-preview, vous devez effectuer une mise à niveau vers la version 3. Consultez la mise à niveau vers le SDK .NET Azure Search version 3 pour obtenir des instructions.

Tout d’abord, mettez à jour votre référence NuGet pour Microsoft.Azure.Search à l’aide de la console du Gestionnaire de package NuGet ou en cliquant avec le bouton droit sur les références de votre projet et en sélectionnant « Gérer les packages NuGet ... » dans Visual Studio.

Une fois Que NuGet a téléchargé les nouveaux packages et leurs dépendances, régénérez votre projet.

Si vous utilisiez précédemment la version 1.0.0-preview, 1.0.1-preview ou 1.0.2-preview, la build doit réussir et vous êtes prêt à y aller !

Si vous utilisiez précédemment la version 0.13.0-preview ou une version antérieure, vous devez voir les erreurs de génération comme suit :

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?)

L’étape suivante consiste à corriger les erreurs de build une par une. La plupart nécessitent la modification de certains noms de classe et de méthode qui ont été renommés dans le Kit de développement logiciel (SDK). Liste des changements majeurs dans la version 1.1 contient la liste des changements de nom.

Si vous utilisez des classes personnalisées pour modéliser vos documents et que ces classes ont des propriétés de types primitifs non nullables (par exemple, int ou bool en C#), il existe un correctif de bogue dans la version 1.1 du Kit de développement logiciel (SDK) dont vous devez être conscient. Pour plus d’informations, consultez correctifs de bogues dans la version 1.1.

Enfin, une fois que vous avez résolu toutes les erreurs de génération, vous pouvez apporter des modifications à votre application pour tirer parti des nouvelles fonctionnalités si vous le souhaitez.

Liste des modifications majeures dans la version 1.1

La liste suivante est triée selon la probabilité que la modification affecte votre code d’application.

Modifications d’IndexBatch et d’IndexAction

IndexBatch.Create a été renommé en IndexBatch.New et n’a plus d’argument params. Vous pouvez utiliser IndexBatch.New pour les lots qui mélangent différents types d’actions (fusions, suppressions, etc.). En outre, il existe de nouvelles méthodes statiques pour créer des lots où toutes les actions sont identiques : Delete, Merge, MergeOrUploadet Upload.

IndexAction n’a plus de constructeurs publics et ses propriétés sont désormais immuables. Vous devez utiliser les nouvelles méthodes statiques pour créer des actions à des fins différentes : Delete, Merge, MergeOrUploadet Upload. IndexAction.Create a été supprimé. Si vous avez utilisé la surcharge qui accepte un seul document, veillez à utiliser Upload à la place.

Exemple :

Si votre code ressemble à ceci :

var batch = IndexBatch.Create(documents.Select(doc => IndexAction.Create(doc)));
indexClient.Documents.Index(batch);

Vous pouvez le modifier pour résoudre les erreurs de build :

var batch = IndexBatch.New(documents.Select(doc => IndexAction.Upload(doc)));
indexClient.Documents.Index(batch);

Si vous le souhaitez, vous pouvez le simplifier davantage :

var batch = IndexBatch.Upload(documents);
indexClient.Documents.Index(batch);

Modifications de l'indexBatchException

La propriété IndexBatchException.IndexResponse a été renommée IndexingResultset son type est désormais IList<IndexingResult>.

Exemple :

Si votre code ressemble à ceci :

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)));
}

Vous pouvez le modifier pour résoudre les erreurs de build :

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)));
}

Modifications de méthode d’opération

Chaque opération du Kit de développement logiciel (SDK) .NET Recherche Azure est exposée sous la forme d’un ensemble de surcharges de méthode pour les appelants synchrones et asynchrones. Les signatures et le factoring de ces surcharges de méthode ont changé dans la version 1.1.

Par exemple, l’opération « Obtenir des statistiques d’index » dans les versions antérieures du Kit de développement logiciel (SDK) a exposé ces signatures :

Dans IIndexOperations :

// Asynchronous operation with all parameters
Task<IndexGetStatisticsResponse> GetStatisticsAsync(
    string indexName,
    CancellationToken cancellationToken);

Dans 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);

Les signatures de méthode pour la même opération dans la version 1.1 ressemblent à ceci :

Dans 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));

Dans 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));

À compter de la version 1.1, le Kit de développement logiciel (SDK) .NET Recherche Azure organise les méthodes d’opération différemment :

  • Les paramètres facultatifs sont désormais modélisés comme paramètres par défaut plutôt que des surcharges de méthode supplémentaires. Cela réduit le nombre de surcharges de méthode, parfois considérablement.
  • Les méthodes d’extension masquent désormais beaucoup de détails superflus du protocole HTTP de l’appelant. Par exemple, les versions antérieures du Kit de développement logiciel (SDK) ont retourné un objet de réponse avec un code d’état HTTP, que vous n’avez souvent pas besoin de vérifier, car les méthodes d’opération lèvent CloudException pour tout code d’état qui indique une erreur. Les nouvelles méthodes d’extension retournent simplement des objets de modèle, ce qui vous évite d’avoir à les décompresser dans votre code.
  • À l’inverse, les interfaces principales exposent désormais des méthodes qui vous donnent plus de contrôle au niveau HTTP si vous en avez besoin. Vous pouvez désormais transmettre des en-têtes HTTP personnalisés à inclure dans les requêtes, et le nouveau type de retour AzureOperationResponse<T> vous donne un accès direct aux HttpRequestMessage et HttpResponseMessage pour l’opération. AzureOperationResponse est défini dans l’espace de noms Microsoft.Rest.Azure et remplace Hyak.Common.OperationResponse.

Modifications de "ScoringParameters"

Une nouvelle classe nommée ScoringParameter a été ajoutée dans le kit SDK le plus récent pour faciliter la fourniture de paramètres aux profils de scoring dans une requête de recherche. Auparavant, la propriété ScoringProfiles de la classe SearchParameters était typée comme IList<string>; maintenant, elle est typée comme IList<ScoringParameter>.

Exemple :

Si votre code ressemble à ceci :

var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured";      // Use a scoring profile
sp.ScoringParameters = new[] { "featuredParam-featured", "mapCenterParam-" + lon + "," + lat };

Vous pouvez le modifier pour résoudre les erreurs de build :

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))
    };

Modifications apportées à la classe de modèle

En raison des modifications de signature décrites dans méthode Operation change, de nombreuses classes de l’espace de noms Microsoft.Azure.Search.Models ont été renommées ou supprimées. Par exemple:

  • IndexDefinitionResponse a été remplacé par AzureOperationResponse<Index>
  • DocumentSearchResponse a été renommé en DocumentSearchResult
  • IndexResult a été renommé en IndexingResult
  • Documents.Count() retourne maintenant un long avec le nombre de documents au lieu d’un DocumentCountResponse
  • IndexGetStatisticsResponse a été renommé en IndexGetStatisticsResult
  • IndexListResponse a été renommé en IndexListResult

Pour résumer, OperationResponseclasses dérivées qui existaient uniquement pour encapsuler un objet modèle ont été supprimées. Les classes restantes ont vu leur suffixe changer de Response à Result.

Exemple :

Si votre code ressemble à ceci :

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;

Vous pouvez le modifier pour résoudre les erreurs de build :

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;

Classes de réponse et IEnumerable

Une modification supplémentaire qui peut affecter votre code est que les classes de réponse qui contiennent des collections n’implémentent plus IEnumerable<T>. Au lieu de cela, vous pouvez accéder directement à la propriété de collection. Par exemple, si votre code ressemble à ceci :

DocumentSearchResponse<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response)
{
    Console.WriteLine(result.Document);
}

Vous pouvez le modifier pour résoudre les erreurs de build :

DocumentSearchResult<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response.Results)
{
    Console.WriteLine(result.Document);
}

Cas spécial pour les applications web

Si vous disposez d’une application web qui sérialise DocumentSearchResponse directement pour envoyer des résultats de recherche au navigateur, vous devez modifier votre code ou les résultats ne sérialisent pas correctement. Par exemple, si votre code ressemble à ceci :

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)
    };
}

Vous pouvez le modifier en obtenant la propriété .Results de la réponse de recherche pour corriger le rendu des résultats de recherche :

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
    };
}

Vous devrez rechercher de tels cas dans votre code vous-même ; Le compilateur ne vous avertit pas, car JsonResult.Data est de type object.

Modifications de Cloud Exception

La classe CloudException est passée de l’espace de noms Hyak.Common à l’espace de noms Microsoft.Rest.Azure. En outre, sa propriété Error a été renommée Body.

Modifications de SearchServiceClient et SearchIndexClient

Le type de la propriété Credentials a changé de SearchCredentials à sa classe de base, ServiceClientCredentials. Si vous devez accéder au SearchCredentials d’un SearchIndexClient ou d’un SearchServiceClient, veuillez utiliser la nouvelle propriété SearchCredentials.

Dans les versions antérieures du Kit de développement logiciel (SDK), SearchServiceClient et SearchIndexClient disposaient de constructeurs qui prenaient un paramètre HttpClient. Ceux-ci ont été remplacés par des constructeurs prenant un HttpClientHandler et un tableau d'objets DelegatingHandler. Cela facilite l’installation de gestionnaires personnalisés pour prétraiter les requêtes HTTP si nécessaire.

Enfin, les constructeurs qui prenaient un Uri et un SearchCredentials ont changé. Par exemple, si vous avez du code qui ressemble à ceci :

var client =
    new SearchServiceClient(
        new SearchCredentials("abc123"),
        new Uri("http://myservice.search.windows.net"));

Vous pouvez le modifier pour résoudre les erreurs de build :

var client =
    new SearchServiceClient(
        new Uri("http://myservice.search.windows.net"),
        new SearchCredentials("abc123"));

Notez également que le type du paramètre d’informations d’identification a changé en ServiceClientCredentials. Il est peu probable d’affecter votre code, car SearchCredentials est dérivé de ServiceClientCredentials.

Transmission d’un identifiant de demande

Dans les versions antérieures du Kit de développement logiciel (SDK), vous pouvez définir un ID de demande sur le SearchServiceClient ou SearchIndexClient et il est inclus dans chaque requête à l’API REST. Cela est utile pour résoudre les problèmes liés à votre service de recherche si vous devez contacter le support technique. Toutefois, il est plus utile de définir un ID de requête unique pour chaque opération plutôt que d’utiliser le même ID pour toutes les opérations. Pour cette raison, les méthodes SetClientRequestId de SearchServiceClient et de SearchIndexClient ont été supprimées. Au lieu de cela, vous pouvez transmettre un ID de requête à chaque méthode d’opération via le paramètre facultatif SearchRequestOptions.

Remarque

Dans une prochaine version du Kit de développement logiciel (SDK), nous allons ajouter un nouveau mécanisme permettant de définir un ID de requête globalement sur les objets clients qui sont cohérents avec l’approche utilisée par d’autres kits sdk Azure.

Exemple :

Si vous avez du code qui ressemble à ceci :

client.SetClientRequestId(Guid.NewGuid());
...
long count = client.Documents.Count();

Vous pouvez le modifier pour résoudre les erreurs de build :

long count = client.Documents.Count(new SearchRequestOptions(requestId: Guid.NewGuid()));

Modifications du nom de l’interface

Les noms d’interface de groupe d’opérations ont tous changé pour être cohérents avec leurs noms de propriétés correspondants :

  • Le type de ISearchServiceClient.Indexes a été renommé de IIndexOperations en IIndexesOperations.
  • Le type de ISearchServiceClient.Indexers a été renommé de IIndexerOperations en IIndexersOperations.
  • Le type de ISearchServiceClient.DataSources a été renommé de IDataSourceOperations en IDataSourcesOperations.
  • Le type de ISearchIndexClient.Documents a été renommé de IDocumentOperations en IDocumentsOperations.

Cette modification n’affecte pas votre code, sauf si vous avez créé des maquettes de ces interfaces à des fins de test.

Correctifs de bogues dans la version 1.1

Un bogue s’est produit dans les versions antérieures du Kit de développement logiciel (SDK) .NET Recherche Azure concernant la sérialisation des classes de modèle personnalisées. Le bogue peut se produire si vous avez créé une classe de modèle personnalisée avec une propriété d’un type valeur non nullable.

Étapes à reproduire

Créez une classe de modèle personnalisée avec une propriété de type valeur non nullable. Par exemple, ajoutez une propriété de type UnitCount publique de type int au lieu de int?.

Si vous indexez un document avec la valeur par défaut de ce type (par exemple, 0 pour int), le champ est null dans Recherche Azure. Si vous recherchez ensuite ce document, l'appel Search lèvera JsonSerializationException car il ne peut pas convertir null en int.

En outre, les filtres peuvent ne pas fonctionner comme prévu, car la valeur Null a été écrite dans l’index au lieu de la valeur prévue.

Corriger les détails

Nous avons résolu ce problème dans la version 1.1 du Kit de développement logiciel (SDK). Maintenant, si vous avez une classe de modèle comme celle-ci :

public class Model
{
    public string Key { get; set; }

    public int IntValue { get; set; }
}

et vous définissez IntValue sur 0, cette valeur est maintenant correctement sérialisée comme 0 sur le câble et stockée sous la forme 0 dans l’index. L’aller-retour fonctionne également comme prévu.

Il existe un problème potentiel à connaître avec cette approche : si vous utilisez un type de modèle avec une propriété non nullable, vous devez garantir qu’aucun document de votre index ne contient une valeur Null pour le champ correspondant. Ni le Kit de développement logiciel (SDK) ni l’API REST Recherche Azure ne vous aideront à l’appliquer.

Ce n’est pas seulement une préoccupation hypothétique : imaginez un scénario où vous ajoutez un nouveau champ à un index existant de type Edm.Int32. Après la mise à jour de la définition d’index, tous les documents auront une valeur Null pour ce nouveau champ (étant donné que tous les types sont nullables dans Recherche Azure). Si vous utilisez ensuite une classe de modèle avec une propriété int non nullable pour ce champ, vous obtiendrez un JsonSerializationException comme suit lors de la tentative de récupération de documents :

Error converting value {null} to type 'System.Int32'. Path 'IntValue'.

Pour cette raison, nous vous recommandons toujours d’utiliser des types nullables dans vos classes de modèle comme meilleure pratique.

Pour plus d’informations sur ce bogue et le correctif, consultez ce problème sur GitHub.