2017-07-26 2 views
0

Je travaille sur un service Web ASP.NET MVC. Dans une page Web, lorsqu'un utilisateur clique sur un bouton, cela déclenche une méthode complexe qui prend un peu de temps pour se terminer. Je souhaite rediriger l'utilisateur vers une page en attente et, lorsque le processus est terminé, rediriger l'utilisateur vers une nouvelle page.Utilisation d'événements pour déclencher ActionResult dans ASP.NET MVC

Lorsque le processus est terminé, il déclenche un événement, que je peux écouter depuis le contrôleur. Mais je ne peux pas faire la dernière étape pour travailler (le contrôleur redirigeant vers la nouvelle page lors de la réception de l'événement).

Voici ma tentative très naïve à le faire (avec des noms plus simples):

public MyController() 
    { 
     EventsControllerClass.ProcessComplete += new EventHandler<MyArgsClass>(OnEventReceived); 
    } 

    private void OnEventReceived(object sender, MyArgsClass eventArguments) 
    { 
     RedirectToPage(); 
    } 

    private ActionResult RedirectToPage() 
    { 
     return RedirectToAction("PageName"); 
    } 
+0

Vous devez implémenter la synchronisation pour cela. –

+0

Merci, je vais essayer de regarder ça! – Pablo

Répondre

0

Après plusieurs jours de travail à ce sujet, j'ai une solution viable. Ce n'est peut-être pas joli, mais ça marche, et peut-être que certaines idées peuvent être utiles pour d'autres personnes, alors voici:

Je vais expliquer la solution à mon problème particulier: J'ai besoin d'un bouton pour rediriger vers un "attente "page pendant qu'un processus plus long s'exécute en arrière-plan et soulève un événement quand il est terminé. Lorsque cet événement est reçu, nous voulons rediriger l'utilisateur (automatiquement) vers une dernière page.

D'abord, j'ai créé une classe pour écouter l'événement. J'ai essayé de le faire directement dans le contrôleur, mais vous devez faire attention à ne pas signer et ne pas signer, car apparemment les contrôleurs sont créés et détruits à chaque requête. Dans cette "classe d'écoute", j'ai une propriété booléenne qui est définie sur "true" quand l'événement est reçu.

Lorsque la première action est déclenchée, le contrôleur redirige normalement à la page « attendre », où j'ai ce script Java simple redirection vers la nouvelle action:

<script type="text/javascript"> 
    window.location = "@Url.Action("WaitThenRedirect", "AuxiliaryControllerName")"; 
</script> 

Ce met en mouvement le long processus (à travers un autre événement). La clé est que je le fais avec une action asynchrone (ce contrôleur hérite de AsyncController). (Remarque J'ai utilisé un contrôleur auxiliaire Cela permet de garder toutes les choses asynchrones en dehors..) Voilà comment cela ressemble (more info here):

public static event EventHandler<AuxiliaryEventsArgs> ProcessReady; 

public void WaitThenRedirectAsync() 
{ 
    AsyncManager.OutstandingOperations.Increment(); 
    ProcessReady += (sender, e) => 
    { 
     AsyncManager.Parameters["success"] = e.success; 
     AsyncManager.OutstandingOperations.Decrement(); 
    }; 
    WaitForEvent(); 
} 

public ActionResult WaitThenRedirectCompleted(bool success) 
{ 
    if (success) 
    { 
     return RedirectToAction("RedirectToView", "ControllerName"); 
    } 
    else 
    { 
     return RedirectToAction("UnexpectedError", "ControllerName"); 
    } 
} 

private void WaitForEvent() 
{ 
    bool isWaitSuccessful = true; 
    int waitingLoops = 0; 
    int waitingThreshold = 200; 
    int sleepPeriod = 100; // (milliseconds) 
    while (!EventsListener.IsTheThingReady()) 
    { 
     System.Threading.Thread.Sleep(sleepPeriod); 
     ++waitingLoops; 
     if (waitingLoops > waitingThreshold) 
     { 
      System.Diagnostics.Debug.WriteLine("Waiting timed out!"); 
      isWaitSuccessful = false; 
      break; 
     } 
    } 
    isWaitSuccessful = true; 

    if (null != ProcessReady) 
    { 
     AuxiliaryEventsArgs arguments = new AuxiliaryEventsArgs(); 
     arguments.success = isWaitSuccessful; 
     try 
     { 
      ProcessReady(null, arguments); 
     } 
     catch (Exception ex) 
     { 
      System.Diagnostics.Debug.WriteLine("Error in event ProcessReady" + ex); 
     } 
    } 
} 

Je crois qu'il est possible d'utiliser la syntaxe ajax pour des solutions alternatives, mais cela est ce que j'ai et ça marche bien. Je crois que ce n'est pas un besoin très commun, mais j'espère que quelqu'un en bénéficiera!