2016-11-15 4 views
4

Ich habe eine Middleware in meiner asp.net-Kernanwendung eingerichtet, um Controlleraktionen in einer Transaktion automatisch zu umbrechen.Übergeben Sie Informationen an Middleware von Controller

public async Task Invoke(HttpContext context, MyDataContext dbContext) 
{ 
    if (context.Request.Method == "GET") 
    { 
     await _next(context); 
    } 
    else 
    { 
     using (var transaction = await dbContext.Database.BeginTransactionAsync()) 
     { 
      try 
      { 
       await _next(context); 
       transaction.Commit(); 
      } 
      catch (Exception) 
      { 
       transaction.Rollback(); 
       throw; 
      } 
     } 
    } 
} 

Allerdings habe ich eine Controller-Methode (möglicherweise mehr in der Zukunft), die in einer Transaktion nicht ausgeführt werden sollte. Was wäre der beste Weg, um mit dieser Controller-Aktion die Middleware-Funktionalität zu deaktivieren?

Es wäre schön, ein benutzerdefiniertes Attribut wie [NoTransaction] auf einer Controller-Methode zu platzieren. Allerdings kann ich nicht feststellen, ob es eine Möglichkeit gibt, zu lösen, von der Invoke() -Methode meiner Middleware, genau die Controller-Aktion wird aufgerufen (was würde ich die Attribute von dieser Methode abrufen und bestimmen, ob zu erstellen eine Transaktion.) Was wäre der richtige Weg, dies zu tun?

Antwort

1

Ich denke, was Sie suchen, ist ein benutzerdefinierter Filter.

Sie könnten eine neue Klasse erstellen, die von ActionFilterAttribute abgeleitet ist. Dann können Sie die Methoden OnActionExecuting und OnActionExecuted überschreiben, um Ihre Transaktionsverarbeitung hinzuzufügen.

Sie können dann das Attribut filter via den Methoden hinzufügen, unter denen Sie diese ausführen möchten. [CustomFilter] für den Fall, dass Sie Ihre Klasse "CustomFilterAttribute" benannt haben.

Wenn Sie mehr Kontrolle über die Lebensdauer der Filterklasse benötigen, können Sie den ActionFilter als ServiceFilter verwenden. Es erfordert die Registrierung als Dienst und ermöglicht Ihnen auch die Abhängigkeitsinjektion zu verwenden. ServiceFilter Attribute etwas anders aussehen:

[ServiceFilter(typeof(CustomFilter))] 

Eine gute Referenz dafür ist: https://damienbod.com/2015/09/15/asp-net-5-action-filters/

+0

Das klingt interessant, aber ich bin mir nicht sicher, ob ich den Vorschlag zu verstehen - nicht das mir erlauben, systemweite Transaktionen zu haben für Controller-Aktionen standardmäßig, und verwenden Sie dann das Attribut zum Deaktivieren? –

+0

Meine vorgeschlagene Lösung wäre besser mit einem Opt-In-Ansatz ausgestattet und hätte die Transaktionsverarbeitung innerhalb des Filter-Codes. Für den Opting-out sehen Sie sich den Abschnitt "Verwenden des Filters als globalen Filter" in der bereitgestellten Verknüpfung an. Sie können grundsätzlich einen Standardfilter auf alle Controller anwenden. Sie könnten dann einfach einen booleschen Wert als Parameter hinzufügen, um anzugeben, ob Sie eine Transaktion erstellen möchten oder nicht, und das Attribut manuell an einer beliebigen Stelle hinzufügen, an der keine Transaktion erstellt werden soll. – FelschR

+0

Die Methoden des ActionFilter werden am Anfang und am Ende Ihrer Methode aufgerufen. Daher müssen Sie die Transaktion als Mitglied der Klasse definieren. stellen Sie sicher, dass Sie transaction.Dispose() aufrufen; – FelschR

Verwandte Themen