Mam kod w zdarzeniu global.asax
pliku, Application_Error
który jest wykonywany, gdy wystąpi błąd i wysyła do mnie e-mail ze szczegółami błędu.
void Application_Error(object sender, EventArgs e)
{
var error = Server.GetLastError();
if (error.Message != "Not Found")
{
// Send email here...
}
}
Działa to dobrze, gdy uruchamiam go w programie Visual Studio, jednak gdy publikuję na naszym serwerze na żywo, Application_Error
zdarzenie nie jest uruchamiane.
Po kilku testach mogę uzyskać Application_Error
odpalenie, gdy ustawię customErrors="Off"
, jednak ustawienie go z powrotem, aby customErrors="On"
zatrzymać ponowne uruchomienie zdarzenia.
Czy ktoś może zasugerować, dlaczego Application_Error
nie miałby strzelać, gdy customErrors
są włączone w web.config
?
asp.net-mvc-3
application-error
WDuffy
źródło
źródło
Application_Error()
metoda nie została wywołana. Wyjaśniłem również moje ostateczne rozwiązanie.Odpowiedzi:
AKTUALIZACJA
Ponieważ ta odpowiedź dostarcza rozwiązania, nie będę jej edytować, ale znalazłem znacznie czystszy sposób rozwiązania tego problemu. Zobacz moją drugą odpowiedź po szczegóły ...
Oryginalna odpowiedź:
Dowiedziałem się, dlaczego
Application_Error()
metoda nie jest wywoływana ...Global.asax.cs
Domyślnie (podczas generowania nowego projektu) aplikacja MVC ma pewną logikę w
Global.asax.cs
pliku. Ta logika jest używana do mapowania tras i rejestrowania filtrów. Domyślnie rejestruje tylko jeden filtr:HandleErrorAttribute
filtr. Gdy customErrors są włączone (lub przez żądania zdalne, gdy jest ustawiona na RemoteOnly), HandleErrorAttribute informuje MVC, aby szukał widoku błędu i nigdy nie wywołujeApplication_Error()
metody. Nie mogłem znaleźć dokumentacji na ten temat, ale jest to wyjaśnione w tej odpowiedzi na programmers.stackexchange.com .Aby uzyskać metodę ApplicationError () wywoływaną dla każdego nieobsługiwanego wyjątku, po prostu usuń wiersz, który rejestruje filtr HandleErrorAttribute.
Teraz problem jest taki: jak skonfigurować customErrors, aby uzyskać to, czego chcesz ...
Sekcja customErrors jest domyślnie ustawiona na
redirectMode="ResponseRedirect"
. Możesz również określić atrybut defaultRedirect jako trasę MVC. Stworzyłem ErrorController, który był bardzo prosty i zmieniłem mój web.config, aby wyglądał tak ...web.config
Problem z tym rozwiązaniem polega na tym, że przekierowuje ono 302 do adresów URL błędów, a następnie te strony odpowiadają kodem stanu 200. Prowadzi to do indeksowania przez Google stron błędów, co jest złe. Nie jest też bardzo zgodny ze specyfikacją HTTP. Nie chciałem przekierować i zastąpić oryginalnej odpowiedzi moimi niestandardowymi widokami błędów.
Próbowałem się zmienić
redirectMode="ResponseRewrite"
. Niestety ta opcja nie obsługuje tras MVC , tylko statyczne strony HTML lub ASPX. Na początku próbowałem użyć statycznej strony HTML, ale kod odpowiedzi wciąż miał 200, ale przynajmniej nie przekierowywał. Wtedy wpadłem na pomysł z tej odpowiedzi ...Postanowiłem zrezygnować z MVC do obsługi błędów. Stworzyłem
Error.aspx
iPageNotFound.aspx
. Te strony były bardzo proste, ale miały jeden kawałek magii ...Ten blok informuje, że strona ma być obsługiwana z poprawnym kodem stanu. Z grubsza, na stronie PageNotFound.aspx użyłem
HttpStatusCode.NotFound
zamiast tego. Zmieniłem plik web.config, aby wyglądał tak ...Wszystko działało idealnie!
Podsumowanie:
filters.Add(new HandleErrorAttribute());
Application_Error()
metody do rejestrowania wyjątkówW przypadku tego rozwiązania zauważyłem kilka wad.
Istnieją sposoby obejścia tych problemów, ale nie przejmowałem się nimi na tyle, aby wykonać jakąkolwiek dodatkową pracę.
Mam nadzieję, że to pomoże wszystkim!
źródło
<customErrors mode="Off" />
. Usunięciefilters.Add(new HandleErrorAttribute());
lub nie ma żadnego efektu.Rozwiązałem ten problem, tworząc ExceptionFilter i zapisując tam błąd zamiast Application_Error. Wszystko, co musisz zrobić, to dodać wywołanie do w RegisterGlobalFilters
log4netExceptionFilter.cs
Global.asax.cs
źródło
Znalazłem artykuł, który opisuje znacznie bardziej przejrzysty sposób tworzenia niestandardowych stron błędów w aplikacji internetowej MVC3, który nie uniemożliwia rejestrowania wyjątków.
Rozwiązaniem jest użycie
<httpErrors>
elementu<system.webServer>
sekcji.Skonfigurowałem mój Web.config w ten sposób ...
Skonfigurowałem również tak,
customErrors
aby miećmode="Off"
(jak sugeruje artykuł).To sprawia, że odpowiedzi są zastępowane przez akcje ErrorControllera. Oto ten kontroler:
Widoki są bardzo proste, po prostu użyłem standardowej składni Razor do stworzenia stron.
Samo to powinno wystarczyć do korzystania z niestandardowych stron błędów z MVC.
Potrzebowałem również rejestrowania wyjątków, więc ukradłem rozwiązanie Marka polegające na użyciu niestandardowego filtra ExceptionFilter ...
Ostatnią rzeczą, którą musisz zrobić, jest zarejestrowanie filtra wyjątków w pliku Global.asax.cs :
Wydaje mi się, że jest to znacznie czystsze rozwiązanie niż moja poprzednia odpowiedź i działa tak dobrze, jak potrafię. Podoba mi się to szczególnie dlatego, że nie czułem się jakbym walczył z frameworkiem MVC; to rozwiązanie faktycznie to wykorzystuje!
źródło
HTTP Error 500.0 - Internal Server Error The page cannot be displayed because an internal server error has occurred.
ekran błędu, a nie moja żądana/Error/Index
stronaTo able to overwrite global settings in global IIS settings (file: C:\Windows\System32\inetsrv\config \applicationHost.config) should be: <section name="httpErrors" overrideModeDefault="Allow" />
W przypadku ASP.NET MVC5 użyj
Można go znaleźć w
FilterConfig.cs
zApp_Start
folderu.źródło
Podoba mi się odpowiedź Marka za pomocą ExceptionFilter, ale inną opcją, jeśli masz wszystkie kontrolery wywodzące się z tego samego kontrolera podstawowego, jest po prostu zastąpienie OnException w kontrolerze podstawowym. Możesz tam logować się i wysyłać e-maile. Ma to tę zaletę, że można używać wszelkich zależności, które zostały już wprowadzone do kontrolera podstawowego z kontenerem IoC.
Nadal możesz używać swojego IoC z IExceptionFilter, ale konfigurowanie powiązań jest nieco trudniejsze.
źródło
O ile wiem, przekazujesz kontrolę do strony określonej w parametrze url, a powiadomienie o zdarzeniu będzie się znajdować tutaj, a nie Application_Error
Wiele informacji można znaleźć tutaj: http://support.microsoft.com/kb/306355
źródło
Aby obejść ten problem, zostawiłem wyłączone błędy klienta i obsłużyłem wszystkie błędy ze zdarzenia Application_Error w global.asax. Jest to trochę trudne z MVC, ponieważ nie chciałem zwracać przekierowania 301, chciałem zwrócić odpowiednie kody błędów. Więcej szczegółów można znaleźć na moim blogu pod adresem http://www.wduffy.co.uk/blog/using-application_error-in-asp-net-mvcs-global-asax-to-handle-errors/, ale ostateczny kod to wymienione poniżej...
A oto kontroler
źródło
Response.StatusCode = ###;
pokazywał wbudowane strony błędów MVC pod adresemC:\inetpub\custerr\en-US
. Nie podobał mi się również pomysł ręcznego wywoływania HttpHandlers lub Controllerów z mojej metody Application_Error (). Cieszę się jednak, że znalazłeś rozwiązanie swojego problemu, wiem, jakie bóle głowy mi to przysporzyło.Ten wpis na blogu pomógł mi:
http://asp-net.vexedlogic.com/2011/04/23/asp-net-maximum-request-length-exceeded/
Jeśli używasz usług IIS 7.0 lub nowszych, możesz zmienić plik Web.config, aby obsługiwał zbyt duże żądania. Istnieją pewne zastrzeżenia, ale oto przykład:
Dodatkowe szczegóły dotyczące tych elementów pliku konfiguracyjnego znajdują się tutaj:
http://www.iis.net/ConfigReference/system.webServer/security/requestFiltering/requestLimits
Kod stanu 404.13 jest zdefiniowany jako „Zbyt duża długość treści”. Należy zwrócić uwagę na to, że wartość
maxAllowedContentLength
jest podawana w bajtach. Różni się to odmaxRequestLength
ustawienia, które znajdziesz w<system.web>
sekcji, które jest określone w kilobajtach.Należy również pamiętać, że
path
atrybut musi być ścieżką bezwzględną, gdyresponseMode
jestRedirect
, więc w razie potrzeby dodaj nazwę katalogu wirtualnego na początku. Pouczające odpowiedzi Jessego Webba pokazują, jak to zrobićresponseMode="ExecuteURL"
, i myślę, że to podejście też się sprawdzi.To podejście nie działa, jeśli tworzysz przy użyciu Visual Studio Development Server (Cassini, serwer sieci Web zintegrowany z Visual Studio). Zakładam, że zadziałaby w IIS Express, ale nie testowałem tego.
źródło
Miałem ten sam problem, kiedy
Application_Error()
nie zostałem trafiony. Próbowałem wszystkiego, aż w końcu przeszedłem przez to, co się działo. Miałem jakiś niestandardowy kod w zdarzeniu ELMAH, które dodawało JSON do wysyłanego e-maila, i był tam błąd zerowy!Naprawienie błędu wewnętrznego pozwoliło kodowi kontynuować
Application_Error()
zdarzenie zgodnie z oczekiwaniami.źródło