ASP.NET MVC 4에서 사용자 지정 오류 페이지를 작동시키는 방법
500, 404 및 403에 대해 사용자 정의 오류 페이지를 표시하고 싶습니다. 수행 한 작업은 다음과 같습니다.
web.config에서 다음과 같이 사용자 정의 오류를 활성화했습니다.
<customErrors mode="On" defaultRedirect="~/Views/Shared/Error.cshtml"> <error statusCode="403" redirect="~/Views/Shared/UnauthorizedAccess.cshtml" /> <error statusCode="404" redirect="~/Views/Shared/FileNotFound.cshtml" /> </customErrors>
다음과 같이 클래스
HandleErrorAttribute
에서 전역 액션 필터로 등록 되었습니다FilterConfig
.public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomHandleErrorAttribute()); filters.Add(new AuthorizeAttribute()); }
위의 각 메시지에 대한 사용자 정의 오류 페이지를 작성했습니다. 500의 기본 값은 이미 기본적으로 사용 가능합니다.
각 사용자 정의 오류 페이지보기에서 페이지의 모델이
System.Web.Mvc.HandleErrorInfo
500의 경우 사용자 정의 오류 페이지가 표시됩니다. 다른 사람들에게는 그렇지 않습니다.
내가 놓친 것이 있습니까?
클래스 의 OnException
메소드 에서 코드를 읽을 때 사용자 정의 오류가 표시되는 것은 아니며 HandleErrorAttribute
500 개만 처리하는 것 같습니다.
다른 오류를 처리하려면 어떻게해야합니까?
내 현재 설정 (MVC3에서 여전히 적용 가능하다고 생각합니다)은에 의존 ErrorController
하므로 다음을 사용합니다.
<system.web>
<customErrors mode="On" defaultRedirect="~/Error">
<error redirect="~/Error/NotFound" statusCode="404" />
</customErrors>
</system.web>
컨트롤러에는 다음이 포함됩니다.
public class ErrorController : Controller
{
public ViewResult Index()
{
return View("Error");
}
public ViewResult NotFound()
{
Response.StatusCode = 404; //you may want to set this to 200
return View("NotFound");
}
}
뷰는 구현 방식과 동일합니다. 그래도 응용 프로그램이 디버그 모드에있는 경우 스택 추적 및 오류 정보를 표시하기 위해 약간의 논리를 추가하는 경향이 있습니다. 따라서 Error.cshtml은 다음과 같습니다.
@model System.Web.Mvc.HandleErrorInfo
@{
Layout = "_Layout.cshtml";
ViewBag.Title = "Error";
}
<div class="list-header clearfix">
<span>Error</span>
</div>
<div class="list-sfs-holder">
<div class="alert alert-error">
An unexpected error has occurred. Please contact the system administrator.
</div>
@if (Model != null && HttpContext.Current.IsDebuggingEnabled)
{
<div>
<p>
<b>Exception:</b> @Model.Exception.Message<br />
<b>Controller:</b> @Model.ControllerName<br />
<b>Action:</b> @Model.ActionName
</p>
<div style="overflow:scroll">
<pre>
@Model.Exception.StackTrace
</pre>
</div>
</div>
}
</div>
파블로 솔루션을 수행했으며 항상 오류가 발생했습니다 (MVC4)
'오류'보기 또는 해당 마스터를 찾을 수 없거나 검색된 위치를 지원하는보기 엔진이 없습니다.
이것을 제거하려면 줄을 제거하십시오
filters.Add(new HandleErrorAttribute());
FilterConfig.cs에서
게시 된 다른 솔루션보다 코딩이 덜 필요한 작업을 수행합니다.
먼저 web.config에 다음이 있습니다.
<customErrors mode="On" defaultRedirect="~/ErrorPage/Oops">
<error redirect="~/ErrorPage/Oops/404" statusCode="404" />
<error redirect="~/ErrorPage/Oops/500" statusCode="500" />
</customErrors>
그리고 컨트롤러 (/Controllers/ErrorPageController.cs)는 다음을 포함합니다 :
public class ErrorPageController : Controller
{
public ActionResult Oops(int id)
{
Response.StatusCode = id;
return View();
}
}
마지막으로보기에는 다음과 같은 내용이 포함되어 있습니다 (단순화를 위해 아래로 분류되었지만 오염 될 수 있음)
@{ ViewBag.Title = "Oops! Error Encountered"; }
<section id="Page">
<div class="col-xs-12 well">
<table cellspacing="5" cellpadding="3" style="background-color:#fff;width:100%;" class="table-responsive">
<tbody>
<tr>
<td valign="top" align="left" id="tableProps">
<img width="25" height="33" src="~/Images/PageError.gif" id="pagerrorImg">
</td>
<td width="360" valign="middle" align="left" id="tableProps2">
<h1 style="COLOR: black; FONT: 13pt/15pt verdana" id="errortype"><span id="errorText">@Response.Status</span></h1>
</td>
</tr>
<tr>
<td width="400" colspan="2" id="tablePropsWidth"><font style="COLOR: black; FONT: 8pt/11pt verdana">Possible causes:</font>
</td>
</tr>
<tr>
<td width="400" colspan="2" id="tablePropsWidth2">
<font style="COLOR: black; FONT: 8pt/11pt verdana" id="LID1">
<hr>
<ul>
<li id="list1">
<span class="infotext">
<strong>Baptist explanation: </strong>There
must be sin in your life. Everyone else opened it fine.<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Presbyterian explanation: </strong>It's
not God's will for you to open this link.<br>
</span>
</li>
<li>
<span class="infotext">
<strong> Word of Faith explanation:</strong>
You lack the faith to open this link. Your negative words have prevented
you from realizing this link's fulfillment.<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Charismatic explanation: </strong>Thou
art loosed! Be commanded to OPEN!<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Unitarian explanation:</strong> All
links are equal, so if this link doesn't work for you, feel free to
experiment with other links that might bring you joy and fulfillment.<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Buddhist explanation:</strong> .........................<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Episcopalian explanation:</strong>
Are you saying you have something against homosexuals?<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Christian Science explanation: </strong>There
really is no link.<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Atheist explanation: </strong>The only
reason you think this link exists is because you needed to invent it.<br>
</span>
</li>
<li>
<span class="infotext">
<strong>Church counselor's explanation:</strong>
And what did you feel when the link would not open?
</span>
</li>
</ul>
<p>
<br>
</p>
<h2 style="font:8pt/11pt verdana; color:black" id="ietext">
<img width="16" height="16" align="top" src="~/Images/Search.gif">
HTTP @Response.StatusCode - @Response.StatusDescription <br>
</h2>
</font>
</td>
</tr>
</tbody>
</table>
</div>
</section>
그것은 그렇게 간단합니다. 더 자세한 오류 정보를 제공하기 위해 쉽게 확장 할 수 있지만 ELMAH 는 나를 위해 처리하며 statusCode 및 statusDescription 만 있으면됩니다.
Global.asax.cs 파일을 사용하는 것이 좋습니다.
protected void Application_Error(Object sender, EventArgs e)
{
var exception = Server.GetLastError();
if (exception is HttpUnhandledException)
{
Server.Transfer("~/Error.aspx");
}
if (exception != null)
{
Server.Transfer("~/Error.aspx");
}
try
{
// This is to stop a problem where we were seeing "gibberish" in the
// chrome and firefox browsers
HttpApplication app = sender as HttpApplication;
app.Response.Filter = null;
}
catch
{
}
}
여기에 여러 단계가 뒤섞인 것 같습니다. 내가 한 일을 처음부터 전달하겠습니다.
ErrorPage
컨트롤러 만들기public class ErrorPageController : Controller { public ActionResult Index() { return View(); } public ActionResult Oops(int id) { Response.StatusCode = id; return View(); } }
이 두 조치에 대한보기를 추가하십시오 (오른쪽 클릭->보기 추가). 이들은 ErrorPage라는 폴더에 나타납니다.
내부를
App_Start
열고FilterConfig.cs
오류 처리 필터를 주석 처리하십시오.public static void RegisterGlobalFilters(GlobalFilterCollection filters) { // Remove this filter because we want to handle errors ourselves via the ErrorPage controller //filters.Add(new HandleErrorAttribute()); }
web.config에서 다음
<customerErrors>
항목을 추가하십시오.System.Web
<customErrors mode="On" defaultRedirect="~/ErrorPage/Oops"> <error redirect="~/ErrorPage/Oops/404" statusCode="404" /> <error redirect="~/ErrorPage/Oops/500" statusCode="500" /> </customErrors>
물론 테스트하십시오. 코드에 처리되지 않은 예외를 던져서 ID가 500 인 페이지로 이동 한 다음 존재하지 않는 페이지의 URL을 사용하여 404를 확인하십시오.
maxspan이 게시 한 답변을 바탕으로 모든 작업 부품을 보여주는 최소 샘플 프로젝트를 GitHub 에 모았습니다 .
기본적으로, 우리 는 예외를 가로 채기 Application_Error
위해 global.asax.cs 에 메소드를 추가하고 우리에게 커스텀 에러 페이지 로 리다이렉트 (또는 더 정확하게 요청을 전송 ) 할 기회를줍니다 .
protected void Application_Error(Object sender, EventArgs e)
{
// See http://stackoverflow.com/questions/13905164/how-to-make-custom-error-pages-work-in-asp-net-mvc-4
// for additional context on use of this technique
var exception = Server.GetLastError();
if (exception != null)
{
// This would be a good place to log any relevant details about the exception.
// Since we are going to pass exception information to our error page via querystring,
// it will only be practical to issue a short message. Further detail would have to be logged somewhere.
// This will invoke our error page, passing the exception message via querystring parameter
// Note that we chose to use Server.TransferRequest, which is only supported in IIS 7 and above.
// As an alternative, Response.Redirect could be used instead.
// Server.Transfer does not work (see https://support.microsoft.com/en-us/kb/320439 )
Server.TransferRequest("~/Error?Message=" + exception.Message);
}
}
오류 컨트롤러 :
/// <summary>
/// This controller exists to provide the error page
/// </summary>
public class ErrorController : Controller
{
/// <summary>
/// This action represents the error page
/// </summary>
/// <param name="Message">Error message to be displayed (provided via querystring parameter - a design choice)</param>
/// <returns></returns>
public ActionResult Index(string Message)
{
// We choose to use the ViewBag to communicate the error message to the view
ViewBag.Message = Message;
return View();
}
}
오류 페이지보기 :
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
</head>
<body>
<h2>My Error</h2>
<p>@ViewBag.Message</p>
</body>
</html>
FilterConfig.csfilters.Add(new HandleErrorAttribute())
에서 비활성화 / 제거 이외의 다른 것은 없습니다
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute()); // <== disable/remove
}
}
구현이 매우 간단하지만이 방법에서 볼 수있는 한 가지 단점은 querystring을 사용하여 예외 정보를 대상 오류 페이지에 전달하는 것입니다.
여기 내 해결책이 있습니다. 사용 [ExportModelStateToTempData] / [ImportModelStateFromTempData]는 내 의견에 불편하다.
~ / Views / Home / Error.cshtml :
@{
ViewBag.Title = "Error";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Error</h2>
<hr/>
<div style="min-height: 400px;">
@Html.ValidationMessage("Error")
<br />
<br />
<button onclick="Error_goBack()" class="k-button">Go Back</button>
<script>
function Error_goBack() {
window.history.back()
}
</script>
</div>
~ / Controllers / HomeController.sc :
public class HomeController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult Error()
{
return this.View();
}
...
}
~ / Controllers / BaseController.sc :
public class BaseController : Controller
{
public BaseController() { }
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is ViewResult)
{
if (filterContext.Controller.TempData.ContainsKey("Error"))
{
var modelState = filterContext.Controller.TempData["Error"] as ModelState;
filterContext.Controller.ViewData.ModelState.Merge(new ModelStateDictionary() { new KeyValuePair<string, ModelState>("Error", modelState) });
filterContext.Controller.TempData.Remove("Error");
}
}
if ((filterContext.Result is RedirectResult) || (filterContext.Result is RedirectToRouteResult))
{
if (filterContext.Controller.ViewData.ModelState.ContainsKey("Error"))
{
filterContext.Controller.TempData["Error"] = filterContext.Controller.ViewData.ModelState["Error"];
}
}
base.OnActionExecuted(filterContext);
}
}
~ / Controllers / MyController.sc :
public class MyController : BaseController
{
public ActionResult Index()
{
return View();
}
public ActionResult Details(int id)
{
if (id != 5)
{
ModelState.AddModelError("Error", "Specified row does not exist.");
return RedirectToAction("Error", "Home");
}
else
{
return View("Specified row exists.");
}
}
}
나는 당신에게 성공적인 프로젝트를 기원합니다 ;-)
모든 것이 설정되었지만 로컬 개발 서버에서 모든 것이 제대로 작동했지만 스테이징 서버에서 상태 코드 500에 대한 적절한 오류 페이지를 여전히 볼 수 없었습니다.
나는 발견 이 블로그 게시물 나를 도와 릭 Strahl에서합니다.
Response.TrySkipIisCustomErrors = true;
사용자 지정 오류 처리 코드 를 추가해야했습니다 .
global.cs를 해킹하지 않고 HandleErrorAttribute로 엉망으로 만들거나 Response.TrySkipIisCustomErrors를 수행하거나 Application_Error를 연결하는 등의 작업을 수행하지 않고도 오류가 올바르게 발생할 수 있습니다.
system.web에서 (보통, 온 / 오프)
<customErrors mode="On">
<error redirect="/error/401" statusCode="401" />
<error redirect="/error/500" statusCode="500" />
</customErrors>
그리고 system.webServer에서
<httpErrors existingResponse="PassThrough" />
이제 상황이 예상대로 작동하고 ErrorController를 사용하여 필요한 것을 표시 할 수 있습니다.
내가 파티에 늦게 온 것 같지만 이것도 더 잘 확인해야합니다.
따라서 system.web
return HttpNotFound ()와 같은 응용 프로그램 내에서 예외를 캐싱하기 위해
<system.web>
<customErrors mode="RemoteOnly">
<error statusCode="404" redirect="/page-not-found" />
<error statusCode="500" redirect="/internal-server-error" />
</customErrors>
</system.web>
그리고 system.webServer
IIS에 의해 잡히고 asp.net 프레임 워크로 향하지 않은 오류를 잡기 위해
<system.webServer>
<httpErrors errorMode="DetailedLocalOnly">
<remove statusCode="404"/>
<error statusCode="404" path="/page-not-found" responseMode="Redirect"/>
<remove statusCode="500"/>
<error statusCode="500" path="/internal-server-error" responseMode="Redirect"/>
</system.webServer>
마지막에서 당신은 다음 변경 클라이언트 응답에 대해 걱정하는 경우 responseMode="Redirect"
에 responseMode="File"
이 하나가 200 응답 코드와 함께 친절한 페이지를 표시하기 때문에, 정적 HTML 파일을 제공합니다.
web.config에서 다음과 같이 system.webserver 태그 아래에 이것을 추가하십시오.
<system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404"/>
<remove statusCode="500"/>
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound"/>
<error statusCode="500" responseMode="ExecuteURL"path="/Error/ErrorPage"/>
</httpErrors>
컨트롤러를 다음과 같이 추가하십시오.
public class ErrorController : Controller
{
//
// GET: /Error/
[GET("/Error/NotFound")]
public ActionResult NotFound()
{
Response.StatusCode = 404;
return View();
}
[GET("/Error/ErrorPage")]
public ActionResult ErrorPage()
{
Response.StatusCode = 500;
return View();
}
}
존경받는 견해를 추가하면 분명히 모든 사람에게 맞는 것 같습니다.
내가 찾은이 솔루션 : Neptune Century
참고 URL : https://stackoverflow.com/questions/13905164/how-to-make-custom-error-pages-work-in-asp-net-mvc-4
'IT story' 카테고리의 다른 글
이 실행 파일에 대한 유효한 프로비저닝 프로파일이 디버그 모드에 없습니다. (0) | 2020.04.11 |
---|---|
계산을 계속할 수 있도록 matplotlib 플롯을 분리하는 방법이 있습니까? (0) | 2020.04.11 |
C ++에서 (-2147483648> 0)이 true를 반환합니까? (0) | 2020.04.11 |
C ++ 컴파일 시간을 단축하기 위해 어떤 기술을 사용할 수 있습니까? (0) | 2020.04.11 |
localStorage를 보거나 편집하는 방법 (0) | 2020.04.11 |