アプリケーション用にカスタムエラーページを設定しています。
<customErrors mode="On" defaultRedirect="~/errors/GeneralError.aspx"
/>
Global.asaxのApplication_Error()では、次のコードが機能して例外の詳細を取得します。
Exception ex = Server.GetLastError();
if (ex != null)
{
if (ex.GetBaseException() != null)
ex = ex.GetBaseException();
}
エラーページ(〜/ errors/GeneralError.aspx.cs)に到達するまでに、Server.GetLastError()はnullです
Global.asax.csではなく、エラーページで例外の詳細を取得する方法はありますか?
Vista/IIS7上のASP.NET 3.5
Web.configのセットアップを詳しく見ると、 この投稿は非常に役に立ちます
asp.net 3.5 sp1には、新しいパラメーターredirectModeがあります。
したがって、customErrors
を修正してこのパラメーターを追加できます。
<customErrors mode="RemoteOnly" defaultRedirect="~/errors/GeneralError.aspx" redirectMode="ResponseRewrite" />
ResponseRewrite
モードを使用すると、ブラウザーをリダイレクトせずに"エラーページ"を読み込むことができるため、URLは変わりません。重要なことに、例外情報は失われません。
OK、この投稿を見つけました: http://msdn.Microsoft.com/en-us/library/aa479319.aspx
この非常に説明的な図で:
(ソース: Microsoft.com )
本質的に、これらの例外の詳細を取得するには、後でカスタムエラーページで取得できるように、それらをGlobal.asaxに保存する必要があります。
global.asaxで大部分の作業を行うのが最良の方法であるようです。カスタムエラーページは、ロジックではなく有用なコンテンツを処理します。
NailItDownとVictorが言ったことの組み合わせ。推奨される/最も簡単な方法は、Global.Asaxを使用してエラーを保存し、カスタムエラーページにリダイレクトすることです。
Global.asax:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
Exception ex = Server.GetLastError();
Application["TheException"] = ex; //store the error for later
Server.ClearError(); //clear the error so we can continue onwards
Response.Redirect("~/myErrorPage.aspx"); //direct user to error page
}
さらに、web.configを設定する必要があります。
<system.web>
<customErrors mode="RemoteOnly" defaultRedirect="~/myErrorPage.aspx">
</customErrors>
</system.web>
そして最後に、error pageに保存した例外を除いて、必要なことをすべて行います。
protected void Page_Load(object sender, EventArgs e)
{
// ... do stuff ...
//we caught an exception in our Global.asax, do stuff with it.
Exception caughtException = (Exception)Application["TheException"];
//... do stuff ...
}
Global.asax.csのServer.Transfer("~/ErrorPage.aspx");
メソッド内からApplication_Error()
のようなものを使用してみてください
次に、ErrorPage.aspx.csのPage_Load()
内から、次のようなことをしても大丈夫です:Exception exception = Server.GetLastError().GetBaseException();
Server.Transfer()
は例外をぶら下げているようです。
ここに私の解決策があります。
Global.aspxの場合:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
//direct user to error page
Server.Transfer("~/ErrorPages/Oops.aspx");
}
Oops.aspxで:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadError(Server.GetLastError());
}
protected void LoadError(Exception objError)
{
if (objError != null)
{
StringBuilder lasterror = new StringBuilder();
if (objError.Message != null)
{
lasterror.AppendLine("Message:");
lasterror.AppendLine(objError.Message);
lasterror.AppendLine();
}
if (objError.InnerException != null)
{
lasterror.AppendLine("InnerException:");
lasterror.AppendLine(objError.InnerException.ToString());
lasterror.AppendLine();
}
if (objError.Source != null)
{
lasterror.AppendLine("Source:");
lasterror.AppendLine(objError.Source);
lasterror.AppendLine();
}
if (objError.StackTrace != null)
{
lasterror.AppendLine("StackTrace:");
lasterror.AppendLine(objError.StackTrace);
lasterror.AppendLine();
}
ViewState.Add("LastError", lasterror.ToString());
}
}
protected void btnReportError_Click(object sender, EventArgs e)
{
SendEmail();
}
public void SendEmail()
{
try
{
MailMessage msg = new MailMessage("webteam", "webteam");
StringBuilder body = new StringBuilder();
body.AppendLine("An unexcepted error has occurred.");
body.AppendLine();
body.AppendLine(ViewState["LastError"].ToString());
msg.Subject = "Error";
msg.Body = body.ToString();
msg.IsBodyHtml = false;
SmtpClient smtp = new SmtpClient("exchangeserver");
smtp.Send(msg);
}
catch (Exception ex)
{
lblException.Text = ex.Message;
}
}
ここにはいくつかの良い答えがありますが、エラーページにシステム例外メッセージを表示するのは良い習慣ではないことを指摘する必要があります(これはあなたがやりたいと思っていることです)。悪意のあるユーザーに望まないことをうっかり開示してしまう可能性があります。たとえば、SQL Serverの例外メッセージは非常に詳細であり、エラーが発生したときにデータベースのユーザー名、パスワード、およびスキーマ情報を提供できます。その情報はエンドユーザーに表示されるべきではありません。
ここで皆が不足していると思う重要な考慮事項の1つは、負荷分散(Webファーム)シナリオです。 global.asaxを実行しているサーバーは、カスタムエラーページの実行に関するサーバーとは異なる場合があるため、Applicationで例外オブジェクトを隠蔽することは信頼できません。
私はまだWebファーム構成のこの問題に対する信頼できる解決策、および/またはカスタムエラーページのServer.GetLastErrorで例外をピックアップできない理由に関するMSからの良い説明を探していますglobal.asax Application_Errorで。
追伸最初にデータをロックしてからロックを解除せずに、アプリケーションコレクションにデータを保存することは安全ではありません。
これは以下の2つのトピックに関連しており、エラーページでGetHtmlErrorMessageとSessionの両方を取得します。
redirectMode = ResponseRewriteのときにHttpContext.Sessionがヌルになる理由
私はServer.Transfer() or Response.Redirect()
を必要としない解決策を試してみました
最初:web.configのResponseRewriteを削除します
Web.config
<customErrors defaultRedirect="errorHandler.aspx" mode="On" />
その後、Global.asax
void Application_Error(object sender, EventArgs e)
{
if(Context.IsCustomErrorEnabled)
{
Exception ex = Server.GetLastError();
Application["TheException"] = ex; //store the error for later
}
}
その後、errorHandler.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string htmlErrorMessage = string.Empty ;
Exception ex = (Exception)Application["TheException"];
string yourSessionValue = HttpContext.Current.Session["YourSessionId"].ToString();
//continue with ex to get htmlErrorMessage
if(ex.GetHtmlErrorMessage() != null){
htmlErrorMessage = ex.GetHtmlErrorMessage();
}
// continue your code
}
参照用
http://www.developer.com/net/asp/article.php/3299641/ServerTransfer-Vs-ResponseRedirect.htm
それは私のために働いた。 MVC 5
in ~\Global.asax
void Application_Error(object sender, EventArgs e)
{
FTools.LogException();
Response.Redirect("/Error");
}
in ~\Controllers
作成ErrorController.cs
using System.Web.Mvc;
namespace MVC_WebApp.Controllers
{
public class ErrorController : Controller
{
// GET: Error
public ActionResult Index()
{
return View("Error");
}
}
}
in ~\Models
作成FunctionTools.cs
using System;
using System.Web;
namespace MVC_WebApp.Models
{
public static class FTools
{
private static string _error;
private static bool _isError;
public static string GetLastError
{
get
{
string cashe = _error;
HttpContext.Current.Server.ClearError();
_error = null;
_isError = false;
return cashe;
}
}
public static bool ThereIsError => _isError;
public static void LogException()
{
Exception exc = HttpContext.Current.Server.GetLastError();
if (exc == null) return;
string errLog = "";
errLog += "**********" + DateTime.Now + "**********\n";
if (exc.InnerException != null)
{
errLog += "Inner Exception Type: ";
errLog += exc.InnerException.GetType() + "\n";
errLog += "Inner Exception: ";
errLog += exc.InnerException.Message + "\n";
errLog += "Inner Source: ";
errLog += exc.InnerException.Source + "\n";
if (exc.InnerException.StackTrace != null)
{
errLog += "\nInner Stack Trace: " + "\n";
errLog += exc.InnerException.StackTrace + "\n";
}
}
errLog += "Exception Type: ";
errLog += exc.GetType().ToString() + "\n";
errLog += "Exception: " + exc.Message + "\n";
errLog += "\nStack Trace: " + "\n";
if (exc.StackTrace != null)
{
errLog += exc.StackTrace + "\n";
}
_error = errLog;
_isError = true;
}
}
}
~\Views
フォルダーの作成Error
および~\Views\Error
の作成Error.cshtml
@using MVC_WebApp.Models
@{
ViewBag.Title = "Error";
if (FTools.ThereIsError == false)
{
if (Server.GetLastError() != null)
{
FTools.LogException();
}
}
if (FTools.ThereIsError == false)
{
<br />
<h1>No Problem!</h1>
}
else
{
string log = FTools.GetLastError;
<div>@Html.Raw(log.Replace("\n", "<br />"))</div>
}
}
ソース: Microsoft ASP.Net
ここにはいくつかの選択肢があると思います。
セッションに最後の例外を保存し、カスタムエラーページから取得できます。または、Application_errorイベント内のカスタムエラーページにリダイレクトすることもできます。後者を選択した場合は、Server.Transferメソッドを使用するようにしてください。