Freigeben über


SOAP-Clientbibliotheksbeispiele für Azure DevOps

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Warnung

Veraltete Technologie – moderne Alternativen empfohlen

Diese SOAP-basierten Clients sind veraltete Technologie und sollten nur für:

  • Verwalten vorhandener Anwendungen, die nicht modernisiert werden können
  • .NET Framework-Anwendungen, die SOAP-spezifische Funktionen erfordern

Verwenden Sie für die neue Entwicklung die modernen REST-basierten .NET-Clientbibliotheken , die Folgendes bieten:

  • ✅ Bessere Leistung und Zuverlässigkeit
  • ✅ Unterstützung für .NET Core, .NET 5+ und .NET Framework
  • ✅ Moderne Authentifizierungsmethoden (verwaltete Identitäten, Dienstprinzipale)
  • ✅ Async/Await-Muster und moderne C#-Funktionen
  • ✅ Aktive Entwicklung und Unterstützung

Dieser Artikel enthält Beispiele für die Integration in Azure DevOps Server und Azure DevOps Services mit älteren SOAP-Clients. Diese Clients sind nur in der .NET Framework-Version verfügbar und erfordern lokale oder ältere Authentifizierungsmethoden.

Voraussetzungen und Einschränkungen

Anforderungen:

  • .NET Framework 4.6.1 oder höher
  • Legacy-NuGet-Pakete
  • Windows-Umgebung für SOAP-Clientunterstützung

Einschränkungen:

  • ❌ Keine .NET Core- oder .NET 5+-Unterstützung
  • ❌ Eingeschränkte moderne Authentifizierungsoptionen
  • ❌ Keine async/await-Muster
  • ❌ Reduzierte Leistung im Vergleich zu REST-Clients
  • ❌ Eingeschränkter zukünftiger Support und Updates

Erforderliche NuGet-Pakete:

Migrationsleitfaden

Schritt 1: Bewerten Sie Ihre aktuelle Nutzung

  • Identifizieren von SOAP-spezifischen Funktionen, die Ihre Anwendung verwendet
  • Ermitteln, ob entsprechende REST-APIs verfügbar sind
  • Evaluieren von Authentifizierungsanforderungen

Schritt 2: Planen der Migrationsstrategie

  • Sofort: Aktualisieren der Authentifizierung, um die Microsoft Entra-ID zu verwenden
  • Kurzfristig: Migrieren zu REST-basierten Clients, während .NET Framework beibehalten wird
  • Langfristig: Modernisieren von .NET Core/.NET 5+ mit REST-Clients

Schritt 3: Implementieren der Migration

  • Beginnen Sie mit Authentifizierungsupdates. Sehen Sie sich die folgenden Beispiele an.
  • Ersetzen von SOAP-Clients durch REST-Entsprechungen inkrementell
  • Testen Sie gründlich, bevor Sie in die Produktionsumgebung bereitstellen.

Ausführliche Anleitungen zur Migration finden Sie unter .NET-Clientbibliotheksbeispiele.

Beispiele für ältere SOAP-Clients

Grundlegende SOAP-Clientverwendung

Von Bedeutung

In diesem Beispiel werden veraltete Muster nur als Referenz gezeigt. Verwenden Sie REST-basierte Beispiele für die neue Entwicklung.

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.VisualStudio.Services.Common;
using System;
using System.Linq;

/// <summary>
/// Legacy SOAP client example - use REST clients for new development
/// Creates a work item query, runs it, and displays results
/// </summary>
public static class LegacySoapExample
{
    public static void ExecuteWorkItemQuery(string collectionUri, string teamProjectName, VssCredentials credentials)
    {
        try
        {
            // Create TfsTeamProjectCollection instance with credentials
            using (var tpc = new TfsTeamProjectCollection(new Uri(collectionUri), credentials))
            {
                // Authenticate the connection
                tpc.Authenticate();
                
                // Get the WorkItemStore service (SOAP-based)
                var workItemStore = tpc.GetService<WorkItemStore>();
                
                // Get the project context
                var workItemProject = workItemStore.Projects[teamProjectName];
                
                // Find 'My Queries' folder
                var myQueriesFolder = workItemProject.QueryHierarchy
                    .OfType<QueryFolder>()
                    .FirstOrDefault(qh => qh.IsPersonal);
                
                if (myQueriesFolder != null)
                {
                    const string queryName = "Legacy SOAP Sample";
                    
                    // Check if query already exists
                    var existingQuery = myQueriesFolder
                        .OfType<QueryDefinition>()
                        .FirstOrDefault(qi => qi.Name.Equals(queryName, StringComparison.OrdinalIgnoreCase));
                    
                    QueryDefinition queryDefinition;
                    if (existingQuery == null)
                    {
                        // Create new query with proper WIQL
                        queryDefinition = new QueryDefinition(
                            queryName,
                            @"SELECT [System.Id], [System.WorkItemType], [System.Title], 
                                     [System.AssignedTo], [System.State], [System.Tags] 
                              FROM WorkItems 
                              WHERE [System.TeamProject] = @project 
                                AND [System.WorkItemType] = 'Bug' 
                                AND [System.State] = 'New'
                              ORDER BY [System.CreatedDate] DESC");
                        
                        myQueriesFolder.Add(queryDefinition);
                        workItemProject.QueryHierarchy.Save();
                    }
                    else
                    {
                        queryDefinition = existingQuery;
                    }
                    
                    // Execute the query
                    var workItems = workItemStore.Query(queryDefinition.QueryText);
                    
                    Console.WriteLine($"Found {workItems.Count} work items:");
                    foreach (WorkItem workItem in workItems)
                    {
                        var title = workItem.Fields["System.Title"].Value;
                        var state = workItem.Fields["System.State"].Value;
                        Console.WriteLine($"#{workItem.Id}: {title} [{state}]");
                    }
                    
                    if (workItems.Count == 0)
                    {
                        Console.WriteLine("No work items found matching the query criteria.");
                    }
                }
                else
                {
                    Console.WriteLine("'My Queries' folder not found.");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error executing SOAP query: {ex.Message}");
            throw;
        }
    }
}

Authentifizierungsmethoden für veraltete Systeme

Warnung

Diese Authentifizierungsmethoden weisen Sicherheitsbeschränkungen auf. Migrieren Sie nach Möglichkeit zur modernen Authentifizierung .

Von Bedeutung

Erwägen Sie die Verwendung der sichereren Microsoft Entra-Token gegenüber den risikoreicheren persönlichen Zugriffstoken. Weitere Informationen finden Sie unter Reduzieren der PAT-Verwendung. Überprüfen Sie die Authentifizierungsanleitungen , um den richtigen Authentifizierungsmechanismus für Ihre Anforderungen auszuwählen.

Wenn Sie einen PAT verwenden müssen, sehen Sie sich Verwenden von persönlichen Zugriffstoken an, um eins zu erstellen. Übergeben Sie es dann als VssBasicCredential:

var credentials = new VssBasicCredential(string.Empty, personalAccessToken);

using (var tpc = new TfsTeamProjectCollection(new Uri(collectionUri), credentials))
{
    tpc.Authenticate();
}

Microsoft Entra-Authentifizierung (eingeschränkter Support)

/// <summary>
/// Microsoft Entra authentication for SOAP services
/// Limited to specific scenarios - prefer REST clients for modern auth
/// </summary>
public static void AuthenticateWithEntraID(string collectionUri)
{
    try
    {
        // Note: Limited authentication options compared to REST clients
        var credentials = new VssAadCredential();
        
        using (var tpc = new TfsTeamProjectCollection(new Uri(collectionUri), credentials))
        {
            tpc.Authenticate();
            Console.WriteLine($"Successfully authenticated with Microsoft Entra ID");
            Console.WriteLine($"Collection: {tpc.DisplayName}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Microsoft Entra authentication failed: {ex.Message}");
        Console.WriteLine("Consider migrating to REST clients for better authentication support.");
        throw;
    }
}

Interaktive Authentifizierung (nur.NET Framework)

/// <summary>
/// Interactive authentication with Visual Studio sign-in prompt
/// Only works in .NET Framework with UI context
/// </summary>
public static void AuthenticateInteractively(string collectionUri)
{
    try
    {
        var credentials = new VssClientCredentials();
        
        using (var tpc = new TfsTeamProjectCollection(new Uri(collectionUri), credentials))
        {
            tpc.Authenticate();
            Console.WriteLine($"Interactive authentication successful");
            Console.WriteLine($"Authenticated user: {tpc.AuthorizedIdentity.DisplayName}");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Interactive authentication failed: {ex.Message}");
        Console.WriteLine("Ensure application has UI context and user interaction is possible.");
        throw;
    }
}

Authentifizierung mit Benutzername/Kennwort (veraltet)

Vorsicht

Die Authentifizierung mit Benutzername/Kennwort ist veraltet und unsicher. Verwenden Sie stattdessen moderne Authentifizierungsmethoden.

/// <summary>
/// Username/password authentication - DEPRECATED AND INSECURE
/// Only use for legacy on-premises scenarios where no alternatives exist
/// </summary>
[Obsolete("Username/password authentication is deprecated. Use modern authentication.")]
public static void AuthenticateWithUsernamePassword(string collectionUri, string username, string password)
{
    try
    {
        var credentials = new VssAadCredential(username, password);
        
        using (var tpc = new TfsTeamProjectCollection(new Uri(collectionUri), credentials))
        {
            tpc.Authenticate();
            Console.WriteLine("Username/password authentication successful (DEPRECATED)");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Username/password authentication failed: {ex.Message}");
        Console.WriteLine("This method is deprecated. Migrate to modern authentication.");
        throw;
    }
}

Veraltetes Beispiel abschließen

using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.VisualStudio.Services.Common;
using System;
using System.Configuration;

/// <summary>
/// Complete example showing legacy SOAP client usage
/// For reference only - use REST clients for new development
/// </summary>
class LegacySoapProgram
{
    static void Main(string[] args)
    {
        try
        {
            // Get configuration (prefer environment variables or secure config)
            var collectionUri = ConfigurationManager.AppSettings["CollectionUri"];
            var projectName = ConfigurationManager.AppSettings["ProjectName"];
            var personalAccessToken = ConfigurationManager.AppSettings["PAT"]; // Store securely
            
            if (string.IsNullOrEmpty(collectionUri) || string.IsNullOrEmpty(projectName))
            {
                Console.WriteLine("Please configure CollectionUri and ProjectName in app.config");
                return;
            }
            
            Console.WriteLine("=== Legacy SOAP Client Example ===");
            Console.WriteLine("WARNING: This uses deprecated SOAP clients.");
            Console.WriteLine("Consider migrating to REST clients for better performance and support.");
            Console.WriteLine();
            
            VssCredentials credentials;
            
            if (!string.IsNullOrEmpty(personalAccessToken))
            {
                // Use PAT authentication (consider migrating to modern auth)
                credentials = new VssBasicCredential(string.Empty, personalAccessToken);
                Console.WriteLine("Using Personal Access Token authentication");
            }
            else
            {
                // Fallback: Interactive authentication (requires UI)
                credentials = new VssClientCredentials();
                Console.WriteLine("Using interactive authentication");
            }
            
            // Execute the legacy SOAP example
            LegacySoapExample.ExecuteWorkItemQuery(collectionUri, projectName, credentials);
            
            Console.WriteLine();
            Console.WriteLine("Example completed successfully.");
            Console.WriteLine("For new development, see: https://docs.microsoft.com/azure/devops/integrate/concepts/dotnet-client-libraries");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
            Console.WriteLine();
            Console.WriteLine("Migration recommendations:");
            Console.WriteLine("1. Update to REST-based client libraries");
            Console.WriteLine("2. Use modern authentication (managed identities, service principals)");
            Console.WriteLine("3. Migrate to .NET Core/.NET 5+ for better performance");
            
            Environment.Exit(1);
        }
        
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }
}

Migration zu modernen Clients

Gegenüberstellung

Legacy-SOAP-Ansatz:

// ❌ Legacy SOAP pattern
using (var tpc = new TfsTeamProjectCollection(uri, credentials))
{
    var workItemStore = tpc.GetService<WorkItemStore>();
    var workItems = workItemStore.Query("SELECT * FROM WorkItems");
    // Synchronous, blocking operations
}

Moderner REST-Ansatz:

// ✅ Modern REST pattern
using var connection = new VssConnection(uri, credentials);
var witClient = connection.GetClient<WorkItemTrackingHttpClient>();
var workItems = await witClient.QueryByWiqlAsync(new Wiql { Query = "SELECT * FROM WorkItems" });
// Asynchronous, non-blocking operations

Wichtige Unterschiede

Merkmal Legacy-SOAP Der moderne REST
Plattformunterstützung Nur .NET Framework .NET Framework, .NET Core, .NET 5+
Leistung Langsamer, synchron Schneller, asynchron
Authentifizierung Eingeschränkte Optionen Vollständiger moderner Support für Autorisierung
API-Abdeckung Nur Ältere APIs Vollständige REST-API-Abdeckung
Zukünftiger Support Nur Wartung Aktive Entwicklung
Codemuster Synchrones Blockieren Async/Wait-Muster strukturieren

Problembehandlung bei Legacy-Clients

Häufige Probleme und Lösungen

Authentifizierungsfehler:

  • Sicherstellen, dass PATs über geeignete Bereiche verfügen
  • Überprüfen des URL-Formats der Organisation (einschließlich Collection für on-premises)
  • Überprüfen der Firewall- und Proxyeinstellungen für SOAP-Endpunkte

Leistungsprobleme:

  • SOAP-Clients sind inhärent langsamer als REST
  • Ziehen Sie batchvorgänge nach Möglichkeit in Betracht.
  • Migrieren zu REST-Clients zur besseren Leistung

Plattformkompatibilität:

  • SOAP-Clients funktionieren nur in .NET Framework
  • Verwenden von REST-Clients für plattformübergreifende Unterstützung

Hilfe erhalten

Für Ältere SOAP-Clientprobleme:

  1. Azure DevOps Developer Community überprüfen
  2. Überprüfen des Migrationsleitfadens für moderne Alternativen
  3. Berücksichtigen sie professionelle Migrationsdienste für große Anwendungen

Migrationsressourcen:

Legacy-Dokumentation:

Von Bedeutung

Planen sie die Migration? Beginnen Sie mit modernen .NET-Clientbibliotheksbeispielen , um die aktuellen bewährten Methoden und Authentifizierungsoptionen anzuzeigen.