共有ホストにデプロイした ASP.NET MVC アプリでカスタム エラーの問題が発生しています。ErrorController を作成し、次のコードを Global.asax に追加して、未処理の例外をキャッチしてログに記録し、制御を ErrorController に移してカスタム エラーを表示します。このコードはここから取られます:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Response.Clear();
HttpException httpEx = ex as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpEx == null)
{
routeData.Values.Add("action", "Index");
}
else
{
switch (httpEx.GetHttpCode())
{
case 404:
routeData.Values.Add("action", "HttpError404");
break;
case 500:
routeData.Values.Add("action", "HttpError500");
break;
case 503:
routeData.Values.Add("action", "HttpError503");
break;
default:
routeData.Values.Add("action", "Index");
break;
}
}
ExceptionLogger.LogException(ex); // <- This is working. Errors get logged
routeData.Values.Add("error", ex);
Server.ClearError();
IController controller = new ErrorController();
// The next line doesn't seem to be working
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
ロギングが正常に機能するため、Application_Error は間違いなく起動しますが、カスタム エラー ページを表示する代わりに、Go Daddy の一般的なエラー ページが表示されます。上記のコードを引用したブログ投稿のタイトルから、MVC フレームワークの Release Candidate 2 を使用していることがわかります。1.0 で、コードの最後の行が機能しないような変更がありましたか? いつものように、私のマシンではうまく機能します。
どんな提案でも大歓迎です。
編集: Web.config の customErrors モードの 3 つの可能性 (オフ、オン、およびリモートのみ) をすべて試したことを忘れていました。この設定に関係なく、同じ結果になります。
編集 2: また、Controller クラスの [HandleError] 装飾の有無にかかわらず試してみました。
更新: 404 を見つけて修正しました。Go Daddy の Hosting Control Center には、404 の動作を制御できる設定パネルのセクションがあり、デフォルトでは一般的なページが表示されます。これにより、Web.config 設定が上書きされるようです。これで、カスタム 404 ページが意図したとおりに表示されるようになりました。ただし、500 と 503 はまだ機能していません。Sql Server が次のように例外をスローした場合に、HomeController にコンテンツの静的テキスト バージョンを取得するコードがあります。
public ActionResult Index()
{
CcmDataClassesDataContext dc = new CcmDataClassesDataContext();
// This might generate an exception which will be handled in the OnException override
HomeContent hc = dc.HomeContents.GetCurrentContent();
ViewData["bodyId"] = "home";
return View(hc);
}
protected override void OnException(ExceptionContext filterContext)
{
// Only concerned here with SqlExceptions so an HTTP 503 message can
// be displayed in the Home View. All others will bubble up to the
// Global.asax.cs and be handled/logged there.
System.Data.SqlClient.SqlException sqlEx =
filterContext.Exception as System.Data.SqlClient.SqlException;
if (sqlEx != null)
{
try
{
ExceptionLogger.LogException(sqlEx);
}
catch
{
// couldn't log exception, continue without crashing
}
ViewData["bodyId"] = "home";
filterContext.ExceptionHandled = true;
HomeContent hc = ContentHelper.GetStaticContent();
if (hc == null)
{
// Couldn't get static content. Display friendly message on Home View.
Response.StatusCode = 503;
this.View("ContentError").ExecuteResult(this.ControllerContext);
}
else
{
// Pass the static content to the regular Home View
this.View("Index", hc).ExecuteResult(this.ControllerContext);
}
}
}
静的コンテンツを取得しようとするコードは次のとおりです。
public static HomeContent GetStaticContent()
{
HomeContent hc;
try
{
string path = Configuration.CcmConfigSection.Config.Content.PathToStaticContent;
string fileText = File.ReadAllText(path);
string regex = @"^[^#]([^\r\n]*)";
MatchCollection matches = Regex.Matches(fileText, regex, RegexOptions.Multiline);
hc = new HomeContent
{
ID = Convert.ToInt32(matches[0].Value),
Title = matches[1].Value,
DateAdded = DateTime.Parse(matches[2].Value),
Body = matches[3].Value,
IsCurrent = true
};
}
catch (Exception ex)
{
try
{
ExceptionLogger.LogException(ex);
}
catch
{
// couldn't log exception, continue without crashing
}
hc = null;
}
return hc;
}
接続文字列を変更して SqlException を生成すると、コードがエラーを適切にログに記録し、静的コンテンツを取得して表示することを確認しました。しかし、Web.config の静的テキスト ファイルへのパスも変更して 503 バージョンのホーム ビューをテストすると、代わりに「サービスを利用できません」以外の何もないページが表示されます。それでおしまい。サイトのルック アンド フィールを備えたカスタム 503 メッセージはありません。
役立つコードの改善に関する提案はありますか? HttpResponse に別のヘッダーを追加すると役に立ちますか? それとも、ゴー・ダディが 503 を強引に乗っ取っているのでしょうか?