次のコードを使用して、ユーザーを asp.net mvc4 アプリケーションのエラー ページにリダイレクトし、ELMAH を使用してエラーを電子メールとして送信しています。
protected void Application_Error()
{
Exception lastException = Server.GetLastError();
//add user specific details
lastException.Data["MachineName"] = Environment.MachineName;
lastException.Data["ClientIP"] = Request.UserHostAddress.ToString();
if (Request.ServerVariables["REMOTE_HOST"] != null)
{
System.Net.IPHostEntry host = new System.Net.IPHostEntry();
host = System.Net.Dns.GetHostEntry(Request.ServerVariables["REMOTE_HOST"]);
lastException.Data["ClientMachineName"] = host.HostName;
}
IController errorController;
HttpException httpException = lastException as HttpException;
RouteData routeData = new RouteData();
//Try catch the error, as NLog throws error in Release mode
System.Diagnostics.EventLog _eventLog = new System.Diagnostics.EventLog("Application", Environment.MachineName, ConfigurationManager.AppSettings[Constants.EventLogSource]);
_eventLog.WriteEntry(lastException.ToString(), System.Diagnostics.EventLogEntryType.Error);
//Possible reason for null is the the server error may not be a proper http exception
if (httpException == null)
{
//Call target Controller
errorController = new ErrorController();
routeData.Values.Add("controller","Error");
routeData.Values.Add("action", "Index");
Response.Clear();
}
else
//It's an Http Exception, Let's handle it.
{
switch (httpException.GetHttpCode())
{
case 404:
//Page not found.
//Call target Controller
errorController = new UserController();
routeData.Values.Add("controller", "User");
routeData.Values.Add("action", "PageNotFound");
break;
case 302:
//Page Temporarily Moved
//Call target Controller
errorController = new UserController();
routeData.Values.Add("controller", "User");
routeData.Values.Add("action", "PageNotFound");
break;
case 500:
//Server error.
//Call target Controller
errorController = new ErrorController();
routeData.Values.Add("controller","Error");
routeData.Values.Add("action", "Index");
break;
//Here you can handle Views to other error codes.
//I choose to redirect to Signin
default:
//Call target Controller
errorController = new ErrorController();
routeData.Values.Add("controller","Error");
routeData.Values.Add("action", "Index");
break;
}
}
//Pass exception details to the target error View.
routeData.Values.Add("error", lastException);
//Clear the error on server.
Server.ClearError();
//Call target Controller and pass the routeData.
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
ローカルでは完全にエラーを返しますが、サーバー(Windows Server 2008 R2、IIS 7.5)からの場合、ELMAHから送信されたメールでページが見つからないというエラーを返します。
ローカル エラー:(完璧です)
System.Web.HttpCompileException: c:\Projects\MVC4\Views\Home\Demo.cshtml(15): error CS0103: The name 'ResolveUrl' does not exist in the current context
Generated: Wed, 18 Apr 2012 07:21:05 GMT
サーバーエラー:(これは正しくありません)
System.InvalidOperationException: The view 'Error' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/Home/Error.aspx ~/Views/Home/Error.ascx ~/Views/Shared/Error.aspx ~/Views/Shared/Error.ascx ~/Views/Home/Error.cshtml ~/Views/Home/Error.vbhtml ~/Views/Shared/Error.cshtml ~/Views/Shared/Error.vbhtml
Generated: Wed, 18 Apr 2012 07:19:11 GMT
System.InvalidOperationException: The view 'Error' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Error.aspx
~/Views/Home/Error.ascx
~/Views/Shared/Error.aspx
~/Views/Shared/Error.ascx
~/Views/Home/Error.cshtml
~/Views/Home/Error.vbhtml
~/Views/Shared/Error.cshtml
~/Views/Shared/Error.vbhtml
at System.Web.Mvc.ViewResult.FindView(ControllerContext context)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
この実装の問題点について何か提案はありますか?