Muszę wykonać działanie kontrolera, gdy użytkownik zostawia stronę (zamknij, odśwież, przejdź do linku itp.). Kod akcji jest jak:

public ActionResult WindowUnload(int token)
    {
        MyObjects[token].Dispose();
        return Content("Disposed");
    }

On Window Pobierz I Rób Ajax Żądanie do akcji:

$(window).unload(function ()
{
    $.ajax({
        type: "POST",
        url: "@Url.Action("WindowUnload")",
        data: {token: "@ViewData["Token"]"},
        cache: false,
        async: true
    });
    //alert("Disposing.");
})

Powyższe żądanie ajax nie przychodzi do mojego kontrolera, tj. Akcja nie jest wykonywana. Aby dokonać powyższego kodu do pracy, muszę odrzucić linię alert, ale nie chcę pożarować alertu na użytkowniku.

Jeśli zmienę async opcja do false (alert jest komentowana), a czasami działa. Na przykład, jeśli odświeżam stronę kilka razy zbyt szybko, a akcja nie zostanie wykonana dla każdego rozładunku.

Jakieś sugestie, jak wykonać akcję na każdym rozładunku bez alertu? Uwaga, nie muszę zwrotu niczego z akcji na stronę.

Zaktualizowano: Podsumowanie odpowiedzi

Nie jest to niezawodnie wykonać prośbę o rozładunek, ponieważ nie jest to właściwe lub oczekiwane zachowanie na rozładowaniu. Więc lepiej przeprojektować aplikację i uniknąć prośby HTTP na rozładowaniu okna. Jeśli nie można uniknąć, istnieją wspólne rozwiązania (opisane w pytaniu):

  1. Zadzwoń ajax synchronicznie, tj., async: false.
    • Plusy: Większość przypadków.
    • plusy: cichy
    • Wady: nie działa w niektórych przypadkach, np, gdy użytkownik odświeża okna kilka razy zbyt szybko (obserwowane w Firefoksie)
  2. Użyj alert na success lub po ajax
    • Plusy: wydaje się działać we wszystkich przypadkach.
    • Wady: nie jest ciche i pożarowe alert pojawiający się.
1
k_rus 24 październik 2011, 16:38

7 odpowiedzi

Najlepsza odpowiedź

To nie działa, a nawet jeśli jesteś w stanie jakoś sprawić, że działa, daje ci dużo bólu głowy, ponieważ nie jest tak, jak powinna być użyta przeglądarka / http. Gdy strona jest rozładowa (w przeglądarce) Przeglądarka zadzwoni do zdarzenia rozładowy, a następnie rozładuj stronę (nie możesz go czekać, nawet moje wykonywanie połączeń z synchronizacji AJAX) i na wypadek, gdy wywołuje połączenie i przeglądarka po wykonaniu połączenia i przeglądarka Kod Rozładuj stronę, połączenie zostanie również anulowane i dlatego, dlaczego czasami widać połączenie na serwerze, a czasami nie działa. Gdybyś mógł powiedzieć, dlaczego chcesz to zrobić, moglibyśmy zasugerować lepsze podejście.

0
Ankur 24 październik 2011, 12:46

Zgodnie z unload dokumentacja, z async: false Powinien działać zgodnie z oczekiwaniami. Jednakże będzie to zawsze broń - na przykład, użytkownik może zostawić swoją stronę, zabijając / rozbijając przeglądarkę i nie otrzymasz żadnego zwrotu pieniędzy. Również wdrażania przeglądarki różnią się również. Obawiam się, że nie dostaniesz żadnych awarii nawet.

3
skolima 24 październik 2011, 12:46

HTTP jest bezpaństwowy i nigdy nie możesz uzyskać niezawodnego sposobu wykrycia, że użytkownik opuścił stronę.

Sugerowane wydarzenia:

  • Limit czasu sesji (jeśli używasz sesji)
  • Aplikacja sięga
  • Timer (należy połączyć z poprzednią sugestią)
  • Usuń poprzedni token, gdy zostanie odwiedzana nowa strona.
3
jgauffin 24 październik 2011, 13:28

Dlaczego tak musi się wydarzyć?

Z fragmentu kodu, które opublikowałeś, próbujesz użyć tego, aby usunąć stronę serwera obiektów? Masz zadzwonić do Uwolnij wszelkie zasoby nie zarządzane Twoje obiekty są używane (takie jak połączenia bazy danych).

Należy to zrobić podczas przetwarzania każdego żądania. Nie powinno być żadnych zasobów niezrównanych w oczekiwaniu na pozbycie się, gdy klient zamyka okno przeglądarki.

Jeśli jest to sposób, w jaki próbujesz to w sposób odnotowany powyżej, należy przerobić kod.

1
Frazell Thomas 24 październik 2011, 13:30

Czy próbowałeś OnBeForeunload () ?

$(window).bind('beforeunload', function() 
    { 
        alert('unloading!'); 
    } 
);

Lub

window.onbeforeunload = function() {
    alert('unloading!'); 
}
1
Steve 24 październik 2011, 13:34

Od komentarza, który wykonałeś @ frazsell, ale brzmi, jak próbujesz zarządzać współbieżnością. Tak więc na szansę, że jest to tutaj dwie popularne metody zarządzania.

Optymistyczna współbieżność

Optymistyczna współbieżność dodaje znacznik czasu do stołu. Gdy klient edytuje rekordowy znacznik czasu jest zawarty w formularzu. Gdy opublikują również aktualizację znacznika czasu, jest również wysłany, a wartość jest sprawdzana, aby upewnić się, że jest to najnowsze w tabeli. Jeśli tak jest, aktualizacja się powiedzie. Jeśli nie jest to, ktoś inny dostał się wcześniej z aktualizacją, więc zostanie odrzucona. Jak sobie to poradzisz, zależy od ciebie.

Pesymistyczna współbieżność

Jeśli często doświadczysz staruszek współbieżnych, pesymistyczna współbieżność może być lepsza. Tutaj, gdy klient edytuje rekordową flagę jest ustawioną na tym wierszu, aby go zablokować. Pozostanie to, dopóki klient zakończy edycję i żaden inny użytkownik nie może edytować tego wiersza. Metoda ta pozwala uniknąć użytkowników utraty zmian, ale dodać podawanie nad głową do aplikacji. Teraz potrzebujesz sposobu uwolnienia niechcianych zamków. Musisz także poinformować użytkownika poprzez UI, że wiersz jest zablokowany do edycji.

W moim doświadczeniu najlepiej zacząć od optymistycznej współbieżności. Jeśli mam wiele osób zgłaszających problemy, spróbuję dowiedzieć się, dlaczego ludzie mają te konflikty. Być może muszę załamać niektóre podmioty do mniejszych typów, ponieważ stały się odpowiedzialne za zbyt wiele miejsc pracy.

1
Keith Bloom 24 październik 2011, 20:43

Nie możesz. Jedyną rzeczą, którą możesz zrobić, to poprosić użytkownika o pozostanie i mieć nadzieję na najlepsze. Istnieje tutaj cała wieloma obawami bezpieczeństwa.

0
Adam Tuliper - MSFT 24 październik 2011, 13:23