Freigeben über


So verwenden Sie das ASP.NET Core-Back-End-Server-SDK

Anmerkung

Dieses Produkt wird eingestellt. Eine Ersetzung für Projekte mit .NET 8 oder höher finden Sie in der Community Toolkit Datasync-Bibliothek.

In diesem Artikel erfahren Sie, wie Sie das ASP.NET Core-Back-End-Server-SDK konfigurieren und verwenden müssen, um einen Datensynchronisierungsserver zu erstellen.

Unterstützte Plattformen

Der ASP.NET Core-Back-End-Server unterstützt ASP.NET 6.0 oder höher.

Datenbankserver müssen die folgenden Kriterien erfüllen, die über ein DateTime- oder Timestamp Typfeld verfügen, das mit Millisekundengenauigkeit gespeichert ist. Repositoryimplementierungen werden für Entity Framework Core und LiteDbbereitgestellt.

Spezifische Datenbankunterstützung finden Sie in den folgenden Abschnitten:

Erstellen eines neuen Datensynchronisierungsservers

Ein Datensynchronisierungsserver verwendet die normalen ASP.NET Core-Mechanismen zum Erstellen des Servers. Sie besteht aus drei Schritten:

  1. Erstellen Sie ein ASP.NET 6.0 -Serverprojekt (oder höher).
  2. Hinzufügen von Entity Framework Core
  3. Hinzufügen von Datensynchronisierungsdiensten

Informationen zum Erstellen eines ASP.NET Core-Diensts mit Entity Framework Core finden Sie in lernprogramm.

Um Datensynchronisierungsdienste zu aktivieren, müssen Sie die folgenden NuGet-Bibliotheken hinzufügen:

Ändern Sie die Program.cs Datei. Fügen Sie die folgende Zeile unter allen anderen Dienstdefinitionen hinzu:

builder.Services.AddDatasyncControllers();

Sie können auch die Vorlage ASP.NET Core datasync-server verwenden:

# This only needs to be done once
dotnet new -i Microsoft.AspNetCore.Datasync.Template.CSharp
mkdir My.Datasync.Server
cd My.Datasync.Server
dotnet new datasync-server

Die Vorlage enthält ein Beispielmodell und einen Controller.

Erstellen eines Tabellencontrollers für eine SQL-Tabelle

Das Standard-Repository verwendet Entity Framework Core. Das Erstellen eines Tabellencontrollers ist ein dreistufiger Prozess:

  1. Erstellen Sie eine Modellklasse für das Datenmodell.
  2. Fügen Sie die Modellklasse der DbContext für Ihre Anwendung hinzu.
  3. Erstellen Sie eine neue TableController<T> Klasse, um Ihr Modell verfügbar zu machen.

Erstellen einer Modellklasse

Alle Modellklassen müssen ITableDataimplementieren. Jeder Repositorytyp verfügt über eine abstrakte Klasse, die ITableDataimplementiert. Das Entity Framework Core-Repository verwendet EntityTableData:

public class TodoItem : EntityTableData
{
    /// <summary>
    /// Text of the Todo Item
    /// </summary>
    public string Text { get; set; }

    /// <summary>
    /// Is the item complete?
    /// </summary>
    public bool Complete { get; set; }
}

Die schnittstelle ITableData stellt die ID des Datensatzes zusammen mit zusätzlichen Eigenschaften für die Verarbeitung von Datensynchronisierungsdiensten bereit:

  • UpdatedAt (DateTimeOffset?) gibt das Datum an, an dem der Datensatz zuletzt aktualisiert wurde.
  • Version (byte[]) stellt einen undurchsichtigen Wert bereit, der sich bei jedem Schreibvorgang ändert.
  • Deleted (bool) ist "true", wenn der Datensatz zum Löschen markiert, aber noch nicht gelöscht wurde.

Die Datensynchronisierungsbibliothek verwaltet diese Eigenschaften. Ändern Sie diese Eigenschaften nicht in Ihrem eigenen Code.

Aktualisieren der DbContext

Jedes Modell in der Datenbank muss im DbContextregistriert werden. Zum Beispiel:

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    public DbSet<TodoItem> TodoItems { get; set; }
}

Erstellen eines Tabellencontrollers

Ein Tabellencontroller ist eine spezielle ApiController. Hier ist ein minimaler Tabellencontroller:

[Route("tables/[controller]")]
public class TodoItemController : TableController<TodoItem>
{
    public TodoItemController(AppDbContext context) : base()
    {
        Repository = new EntityTableRepository<TodoItem>(context);
    }
}

Anmerkung

  • Der Controller muss über eine Route verfügen. Standardmäßig werden Tabellen auf einem Unterpfad von /tablesverfügbar gemacht, können aber überall platziert werden. Wenn Sie Clientbibliotheken vor v5.0.0 verwenden, muss die Tabelle ein Unterpfad von /tablessein.
  • Der Controller muss von TableController<T>erben, wobei <T> eine Implementierung der ITableData Implementierung für Ihren Repositorytyp ist.
  • Weisen Sie ein Repository basierend auf demselben Typ wie Ihr Modell zu.

Implementieren eines Speicher-Repositorys

Sie können auch ein speicherinternes Repository ohne beständigen Speicher verwenden. Fügen Sie einen Singletondienst für das Repository in Ihrem Program.cshinzu:

IEnumerable<Model> seedData = GenerateSeedData();
builder.Services.AddSingleton<IRepository<Model>>(new InMemoryRepository<Model>(seedData));

Richten Sie den Tabellencontroller wie folgt ein:

[Route("tables/[controller]")]
public class ModelController : TableController<Model>
{
    public MovieController(IRepository<Model> repository) : base(repository)
    {
    }
}

Konfigurieren von Tabellencontrolleroptionen

Sie können bestimmte Aspekte des Controllers mithilfe von TableControllerOptionskonfigurieren:

[Route("tables/[controller]")]
public class MoodelController : TableController<Model>
{
    public ModelController(IRepository<Model> repository) : base(repository)
    {
        Options = new TableControllerOptions { PageSize = 25 };
    }
}

Zu den Optionen, die Sie festlegen können, gehören:

  • PageSize (int, Standard: 100) ist die maximale Anzahl von Elementen, die ein Abfragevorgang auf einer einzelnen Seite zurückgegeben hat.
  • MaxTop (int, Standard: 512000) ist die maximale Anzahl von Elementen, die in einem Abfragevorgang ohne Paging zurückgegeben werden.
  • EnableSoftDelete (bool, Standard: false) ermöglicht das Vorläufige Löschen, wodurch Elemente als gelöscht gekennzeichnet werden, anstatt sie aus der Datenbank zu löschen. Das vorläufige Löschen ermöglicht Clients das Aktualisieren des Offlinecaches, erfordert jedoch, dass gelöschte Elemente separat aus der Datenbank gelöscht werden.
  • UnauthorizedStatusCode (int, Standard: 401 Nicht autorisiert) ist der Statuscode, der zurückgegeben wird, wenn der Benutzer keine Aktion ausführen darf.

Konfigurieren von Zugriffsberechtigungen

Standardmäßig kann ein Benutzer alles tun, was er für Entitäten innerhalb einer Tabelle verwenden möchte – einen beliebigen Datensatz erstellen, lesen, aktualisieren und löschen. Um eine differenzierte Kontrolle über die Autorisierung zu erhalten, erstellen Sie eine Klasse, die IAccessControlProviderimplementiert. Die IAccessControlProvider verwendet drei Methoden zum Implementieren der Autorisierung:

  • GetDataView() gibt eine Lambda-Funktion zurück, die angibt, was der verbundene Benutzer sehen kann.
  • IsAuthorizedAsync() bestimmt, ob der verbundene Benutzer die Aktion für die gewünschte Entität ausführen kann.
  • PreCommitHookAsync() passt jede Entität unmittelbar vor dem Schreiben in das Repository an.

Zwischen den drei Methoden können Sie die meisten Zugriffssteuerungsfälle effektiv behandeln. Wenn Sie Zugriff auf die HttpContextbenötigen, einen HttpContextAccessor-konfigurieren.

Im Folgenden wird beispielsweise eine persönliche Tabelle implementiert, in der ein Benutzer nur seine eigenen Datensätze sehen kann.

public class PrivateAccessControlProvider<T>: IAccessControlProvider<T>
    where T : ITableData
    where T : IUserId
{
    private readonly IHttpContextAccessor _accessor;

    public PrivateAccessControlProvider(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }

    private string UserId { get => _accessor.HttpContext.User?.Identity?.Name; }

    public Expression<Func<T,bool>> GetDataView()
    {
      return (UserId == null)
        ? _ => false
        : model => model.UserId == UserId;
    }

    public Task<bool> IsAuthorizedAsync(TableOperation op, T entity, CancellationToken token = default)
    {
        if (op == TableOperation.Create || op == TableOperation.Query)
        {
            return Task.FromResult(true);
        }
        else
        {
            return Task.FromResult(entity?.UserId != null && entity?.UserId == UserId);
        }
    }

    public virtual Task PreCommitHookAsync(TableOperation operation, T entity, CancellationToken token = default)
    {
        entity.UserId == UserId;
        return Task.CompletedTask;
    }
}

Die Methoden sind asynchron, falls Sie eine zusätzliche Datenbanksuche durchführen müssen, um die richtige Antwort zu erhalten. Sie können die IAccessControlProvider<T> Schnittstelle auf dem Controller implementieren, müssen aber dennoch die IHttpContextAccessor übergeben, um auf die HttpContext sicher zuzugreifen.

Um diesen Zugriffssteuerungsanbieter zu verwenden, aktualisieren Sie Ihre TableController wie folgt:

[Authorize]
[Route("tables/[controller]")]
public class ModelController : TableController<Model>
{
    public ModelsController(AppDbContext context, IHttpContextAccessor accessor) : base()
    {
        AccessControlProvider = new PrivateAccessControlProvider<Model>(accessor);
        Repository = new EntityTableRepository<Model>(context);
    }
}

Wenn Sie sowohl nicht authentifizierten als auch authentifizierten Zugriff auf eine Tabelle zulassen möchten, versehen Sie sie mit [AllowAnonymous] anstelle von [Authorize].

Konfigurieren der Protokollierung

Die Protokollierung wird über normalen Protokollierungsmechanismus für ASP.NET Core behandelt. Weisen Sie das ILogger-Objekt der eigenschaft Logger zu:

[Authorize]
[Route("tables/[controller]")]
public class ModelController : TableController<Model>
{
    public ModelController(AppDbContext context, Ilogger<ModelController> logger) : base()
    {
        Repository = new EntityTableRepository<Model>(context);
        Logger = logger;
    }
}

Überwachen von Repositoryänderungen

Wenn das Repository geändert wird, können Sie Workflows auslösen, die Antwort auf den Client protokollieren oder andere Arbeiten in einer von zwei Methoden ausführen:

Option 1: Implementieren eines PostCommitHookAsync

Die IAccessControlProvider<T>-Schnittstelle stellt eine PostCommitHookAsync() Methode bereit. Die Th PostCommitHookAsync()-Methode wird aufgerufen, nachdem die Daten in das Repository geschrieben wurden, aber bevor die Daten an den Client zurückgegeben werden. Es muss darauf geachtet werden, dass die an den Client zurückgegebenen Daten in dieser Methode nicht geändert werden.

public class MyAccessControlProvider<T> : AccessControlProvider<T> where T : ITableData
{
    public override async Task PostCommitHookAsync(TableOperation op, T entity, CancellationToken cancellationToken = default)
    {
        // Do any work you need to here.
        // Make sure you await any asynchronous operations.
    }
}

Verwenden Sie diese Option, wenn Sie asynchrone Aufgaben als Teil des Hooks ausführen.

Option 2: Verwenden des RepositoryUpdated-Ereignishandlers

Die TableController<T> Basisklasse enthält einen Ereignishandler, der gleichzeitig mit der PostCommitHookAsync()-Methode aufgerufen wird.

[Authorize]
[Route(tables/[controller])]
public class ModelController : TableController<Model>
{
    public ModelController(AppDbContext context) : base()
    {
        Repository = new EntityTableRepository<Model>(context);
        RepositoryUpdated += OnRepositoryUpdated;
    }

    internal void OnRepositoryUpdated(object sender, RepositoryUpdatedEventArgs e) 
    {
        // The RepositoryUpdatedEventArgs contains Operation, Entity, EntityName
    }
}

Aktivieren der Azure App Service Identity

Der ASP.NET Core Data Sync Server unterstützt ASP.NET Core Identityoder ein anderes Authentifizierungs- und Autorisierungsschema, das Sie unterstützen möchten. Um Upgrades von früheren Versionen von Azure Mobile Apps zu unterstützen, stellen wir auch einen Identitätsanbieter bereit, der Azure App Service Identityimplementiert. Um Azure App Service Identity in Ihrer Anwendung zu konfigurieren, bearbeiten Sie Ihre Program.cs:

builder.Services.AddAuthentication(AzureAppServiceAuthentication.AuthenticationScheme)
  .AddAzureAppServiceAuthentication(options => options.ForceEnable = true);

// Then later, after you have created the app
app.UseAuthentication();
app.UseAuthorization();

Datenbankunterstützung

Entity Framework Core richtet keine Wertgenerierung für Datums-/Uhrzeitspalten ein. (Siehe Datum/Uhrzeit-Wertgenerierung). Das Azure Mobile Apps-Repository für Entity Framework Core aktualisiert automatisch das feld UpdatedAt für Sie. Wenn Ihre Datenbank jedoch außerhalb des Repositorys aktualisiert wird, müssen Sie die felder UpdatedAt und Version aktualisieren.

Azure SQL

Erstellen Sie einen Trigger für jede Entität:

CREATE OR ALTER TRIGGER [dbo].[TodoItems_UpdatedAt] ON [dbo].[TodoItems]
    AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    UPDATE 
        [dbo].[TodoItems] 
    SET 
        [UpdatedAt] = GETUTCDATE() 
    WHERE 
        [Id] IN (SELECT [Id] FROM INSERTED);
END

Sie können diesen Trigger entweder mithilfe einer Migration oder unmittelbar nach EnsureCreated() installieren, um die Datenbank zu erstellen.

Azure Cosmos DB

Azure Cosmos DB ist eine vollständig verwaltete NoSQL-Datenbank für leistungsstarke Anwendungen mit beliebiger Größe oder Skalierung. Informationen zur Verwendung von Azure Cosmos DB mit Entity Framework Core finden Sie unter Azure Cosmos DB Provider. Bei Verwendung von Azure Cosmos DB mit Azure Mobile Apps:

  1. Richten Sie den Cosmos-Container mit einem zusammengesetzten Index ein, der die Felder UpdatedAt und Id angibt. Zusammengesetzte Indizes können einem Container über das Azure-Portal, ARM, Bicep, Terraform oder im Code hinzugefügt werden. Hier ist ein Beispiel bicep- Ressourcendefinition:

    resource cosmosContainer 'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers@2023-04-15' = {
        name: 'TodoItems'
        parent: cosmosDatabase
        properties: {
            resource: {
                id: 'TodoItems'
                partitionKey: {
                    paths: [
                        '/Id'
                    ]
                    kind: 'Hash'
                }
                indexingPolicy: {
                    indexingMode: 'consistent'
                    automatic: true
                    includedPaths: [
                        {
                            path: '/*'
                        }
                    ]
                    excludedPaths: [
                        {
                            path: '/"_etag"/?'
                        }
                    ]
                    compositeIndexes: [
                        [
                            {
                                path: '/UpdatedAt'
                                order: 'ascending'
                            }
                            {
                                path: '/Id'
                                order: 'ascending'
                            }
                        ]
                    ]
                }
            }
        }
    }
    

    Wenn Sie eine Teilmenge von Elementen in der Tabelle abrufen, stellen Sie sicher, dass Sie alle Eigenschaften angeben, die an der Abfrage beteiligt sind.

  2. Abgeleitete Modelle aus der ETagEntityTableData Klasse:

    public class TodoItem : ETagEntityTableData
    {
        public string Title { get; set; }
        public bool Completed { get; set; }
    }
    
  3. Fügen Sie der DbContexteine OnModelCreating(ModelBuilder) Methode hinzu. Der Cosmos DB-Treiber für Entity Framework platziert standardmäßig alle Entitäten in denselben Container. Sie müssen mindestens einen geeigneten Partitionsschlüssel auswählen und sicherstellen, dass die EntityTag Eigenschaft als Parallelitätstag gekennzeichnet ist. Der folgende Codeausschnitt speichert beispielsweise die TodoItem Entitäten in ihrem eigenen Container mit den entsprechenden Einstellungen für Azure Mobile Apps:

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<TodoItem>(builder =>
        {
            // Store this model in a specific container.
            builder.ToContainer("TodoItems");
            // Do not include a discriminator for the model in the partition key.
            builder.HasNoDiscriminator();
            // Set the partition key to the Id of the record.
            builder.HasPartitionKey(model => model.Id);
            // Set the concurrency tag to the EntityTag property.
            builder.Property(model => model.EntityTag).IsETagConcurrency();
        });
        base.OnModelCreating(builder);
    }
    

Azure Cosmos DB wird seit v5.0.11 im Microsoft.AspNetCore.Datasync.EFCore NuGet-Paket unterstützt. Weitere Informationen können Sie über die folgenden Links erfahren:

PostgreSQL

Erstellen Sie einen Trigger für jede Entität:

CREATE OR REPLACE FUNCTION todoitems_datasync() RETURNS trigger AS $$
BEGIN
    NEW."UpdatedAt" = NOW() AT TIME ZONE 'UTC';
    NEW."Version" = convert_to(gen_random_uuid()::text, 'UTF8');
    RETURN NEW
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER
    todoitems_datasync
BEFORE INSERT OR UPDATE ON
    "TodoItems"
FOR EACH ROW EXECUTE PROCEDURE
    todoitems_datasync();

Sie können diesen Trigger entweder mithilfe einer Migration oder unmittelbar nach EnsureCreated() installieren, um die Datenbank zu erstellen.

SqLite

Warnung

Verwenden Sie SqLite nicht für Produktionsdienste. SqLite eignet sich nur für die clientseitige Verwendung in der Produktion.

SqLite verfügt nicht über ein Datums-/Uhrzeitfeld, das die Genauigkeit von Millisekunden unterstützt. Daher eignet es sich nicht für alles, außer für Tests. Wenn Sie SqLite verwenden möchten, stellen Sie sicher, dass Sie einen Wertkonverter und einen Wertvergleich für jedes Modell für Datums-/Uhrzeiteigenschaften implementieren. Die einfachste Methode zum Implementieren von Wertkonvertern und Vergleichern ist die OnModelCreating(ModelBuilder) Methode Ihrer DbContext:

protected override void OnModelCreating(ModelBuilder builder)
{
    var timestampProps = builder.Model.GetEntityTypes().SelectMany(t => t.GetProperties())
        .Where(p => p.ClrType == typeof(byte[]) && p.ValueGenerated == ValueGenerated.OnAddOrUpdate);
    var converter = new ValueConverter<byte[], string>(
        v => Encoding.UTF8.GetString(v),
        v => Encoding.UTF8.GetBytes(v)
    );
    foreach (var property in timestampProps)
    {
        property.SetValueConverter(converter);
        property.SetDefaultValueSql("STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')");
    }
    base.OnModelCreating(builder);
}

Installieren Sie einen Updatetrigger, wenn Sie die Datenbank initialisieren:

internal static void InstallUpdateTriggers(DbContext context)
{
    foreach (var table in context.Model.GetEntityTypes())
    {
        var props = table.GetProperties().Where(prop => prop.ClrType == typeof(byte[]) && prop.ValueGenerated == ValueGenerated.OnAddOrUpdate);
        foreach (var property in props)
        {
            var sql = $@"
                CREATE TRIGGER s_{table.GetTableName()}_{prop.Name}_UPDATE AFTER UPDATE ON {table.GetTableName()}
                BEGIN
                    UPDATE {table.GetTableName()}
                    SET {prop.Name} = STRFTIME('%Y-%m-%d %H:%M:%f', 'NOW')
                    WHERE rowid = NEW.rowid;
                END
            ";
            context.Database.ExecuteSqlRaw(sql);
        }
    }
}

Stellen Sie sicher, dass die InstallUpdateTriggers-Methode nur einmal während der Datenbankinitialisierung aufgerufen wird:

public void InitializeDatabase(DbContext context)
{
    bool created = context.Database.EnsureCreated();
    if (created && context.Database.IsSqlite())
    {
        InstallUpdateTriggers(context);
    }
    context.Database.SaveChanges();
}

LiteDB

LiteDB ist eine serverlose Datenbank, die in einer einzigen kleinen DLL bereitgestellt wird, die in verwaltetem .NET C#-Code geschrieben wurde. Es ist eine einfache und schnelle NoSQL-Datenbanklösung für eigenständige Anwendungen. So verwenden Sie LiteDb mit beständigem Datenträgerspeicher:

  1. Installieren Sie das Microsoft.AspNetCore.Datasync.LiteDb-Paket von NuGet.

  2. Fügen Sie dem Program.csein Singleton für die LiteDatabase hinzu:

    const connectionString = builder.Configuration.GetValue<string>("LiteDb:ConnectionString");
    builder.Services.AddSingleton<LiteDatabase>(new LiteDatabase(connectionString));
    
  3. Leiten Sie Modelle von der LiteDbTableDataab:

    public class TodoItem : LiteDbTableData
    {
        public string Title { get; set; }
        public bool Completed { get; set; }
    }
    

    Sie können jedes der BsonMapper Attribute verwenden, die mit dem LiteDb NuGet-Paket bereitgestellt werden.

  4. Erstellen Sie einen Controller mit dem LiteDbRepository:

    [Route("tables/[controller]")]
    public class TodoItemController : TableController<TodoItem>
    {
        public TodoItemController(LiteDatabase db) : base()
        {
            Repository = new LiteDbRepository<TodoItem>(db, "todoitems");
        }
    }
    

OpenAPI-Unterstützung

Sie können die von Datensynchronisierungscontrollern definierte API mit NSwag- oder Swashbuckle-veröffentlichen. Beginnen Sie in beiden Fällen, indem Sie den Dienst wie gewohnt für die ausgewählte Bibliothek einrichten.

NSwag

Befolgen Sie die grundlegenden Anweisungen für die NSwag-Integration, und ändern Sie dann wie folgt:

  1. Fügen Sie Ihrem Projekt Pakete hinzu, um NSwag zu unterstützen. Die folgenden Pakete sind erforderlich:

  2. Fügen Sie folgendes am Anfang ihrer Program.cs Datei hinzu:

    using Microsoft.AspNetCore.Datasync.NSwag;
    
  3. Fügen Sie einen Dienst hinzu, um eine OpenAPI-Definition zu Ihrer Program.cs Datei zu generieren:

    builder.Services.AddOpenApiDocument(options =>
    {
        options.AddDatasyncProcessors();
    });
    
  4. Aktivieren Sie die Middleware für die Bereitstellung des generierten JSON-Dokuments und der Swagger-UI, auch in Program.cs:

    if (app.Environment.IsDevelopment())
    {
        app.UseOpenApi();
        app.UseSwaggerUI3();
    }
    

Wenn Sie zum /swagger Endpunkt des Webdiensts navigieren, können Sie die API durchsuchen. Die OpenAPI-Definition kann dann in andere Dienste importiert werden (z. B. Azure API Management). Weitere Informationen zum Konfigurieren von NSwag finden Sie unter Erste Schritte mit NSwag und ASP.NET Core.

Swashbuckle

Befolgen Sie die grundlegenden Anweisungen für die Swashbuckle-Integration, und ändern Sie dann wie folgt:

  1. Fügen Sie Ihrem Projekt Pakete hinzu, um Swashbuckle zu unterstützen. Die folgenden Pakete sind erforderlich:

  2. Fügen Sie einen Dienst hinzu, um eine OpenAPI-Definition zu Ihrer Program.cs Datei zu generieren:

    builder.Services.AddSwaggerGen(options => 
    {
        options.AddDatasyncControllers();
    });
    builder.Services.AddSwaggerGenNewtonsoftSupport();
    

    Anmerkung

    Die AddDatasyncControllers()-Methode verwendet eine optionale Assembly, die der Assembly entspricht, die Die Tabellencontroller enthält. Der Assembly Parameter ist nur erforderlich, wenn sich die Tabellencontroller in einem anderen Projekt als der Dienst befinden.

  3. Aktivieren Sie die Middleware für die Bereitstellung des generierten JSON-Dokuments und der Swagger-UI, auch in Program.cs:

    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI(options => 
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
            options.RoutePrefix = string.Empty;
        });
    }
    

Mit dieser Konfiguration können Sie im Stammverzeichnis des Webdiensts die API durchsuchen. Die OpenAPI-Definition kann dann in andere Dienste importiert werden (z. B. Azure API Management). Weitere Informationen zum Konfigurieren von Swashbuckle finden Sie unter Erste Schritte mit Swashbuckle und ASP.NET Core.

Begrenzungen

Die ASP.NET Core Edition der Dienstbibliotheken implementiert OData v4 für den Listenvorgang. Wenn der Server im Abwärtskompatibilitätsmodus ausgeführt wird, wird das Filtern nach einer Teilzeichenfolge nicht unterstützt.