2016-03-21 7 views
0

Ich möchte einen API-Aufruf über Attribut vor einer Route Ausführung ausführen. Ich habe einen Kundenaktionsfilter erstellt und die OnExecuting() - Überschreibungsfunktion verwendet..NET MVC Async-Task in Attribut vor Route ausführen

Innerhalb der Funktion erwarte ich einen asynchronen API-Aufruf an einen anderen Server. Während des Debuggens merke ich jedoch, dass die Route ausgeführt wird, bevor der Async-Aufruf abgeschlossen ist. Wie kann ich das erreichen?

[CustomAttribute("Stuff")] 
    [Route("MyRoute")] 
    public async Task<IHttpActionResult> MyRoute() 
    { 
     await anotherAsyncFunction(); 
     return Ok(); 
    } 

Und die Definition des benutzerdefinierten Aktionsfilters.

public class CustomAttribute : ActionFilterAttribute 
{ 
    private string att; 
    public CustomAttribute(string a) 
    { 
     att = a; 
    } 


    public async override void OnActionExecuting(HttpActionContext actionContext) 
    { 


     await MyFirstAsyncFunction(); 


    } 
} 

Leider wird dies nicht beendet, bevor der Routencode ausgeführt wird.

+1

Huch. Sie blockieren einen Anruf basierend auf einem anderen Dienst? Ich würde vorschlagen, diese Route zu vermeiden und sie in die Warteschlange zu stellen und stattdessen nach einer Flagge zu suchen. Du gehst einen rutschigen Abhang entlang. - Kommentar beiseite, Sie müssen die API synchron aufrufen. –

+0

wartet nicht, um es synchrone zu machen? – Tyler

+0

Am besten schauen Sie sich einen ['AsyncHelper'] (http://stackoverflow.com/a/25097498/298053) an und wickeln Sie Ihren Anruf ein. –

Antwort

0

Ich habe einen Kundenaktionsfilter erstellt und die OnExecuting() - Überschreibungsfunktion verwendet.

Wie commenfestgestellt haben, ist dies aufgrund der Verwendung von async void, die nicht eine einfache Möglichkeit bereitstellt für Anrufer für asynchrone Operationen zu warten, zu vervollständigen. Dies ist ein Grund, warum meine async best practices article den Hinweis "async void vermeiden" enthält.

Ich möchte einen API-Aufruf über Attribut vor einer Route Ausführung ausführen.

Leider unterstützt ASP.NET MVC keine asynchronen Filter (sie funktionieren jedoch problemlos auf ASP.NET Core). AFAIK, es gibt keine Pläne, dies dem vorhandenen ASP.NET MVC-Produkt hinzuzufügen. Ihre Optionen bestehen entweder darin, den Code manuell auszuführen (d. H. Innerhalb der Aktion, anstatt ein Attribut zu verwenden) oder Ihren Filter synchron zu machen.

Ich habe gerade HttpResponseMessage Antwort = client.PostAsJsonAsync ("/ api/rotue /", res) .Result;

Dies ist die sync-over-async anti-pattern. Es passiert nur in diesem Fall zu arbeiten. Es wäre besser, HttpClient (das nur async ist) durch WebClient (das Sync unterstützt) zu ersetzen.