redirectMode =“ResponseRewrite”를 설정하면 CustomErrors가 작동하지 않습니다.
이전 사이트에서는 다음을 추가하여 CustomErrors 작동 방식을 변경했습니다 redirectMode="ResponseRewrite"
(3.5 SP1의 새로운 기능).
<customErrors mode="RemoteOnly" defaultRedirect="Error.aspx" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.aspx" />
</customErrors>
문제는 일반 오류 페이지 (설정하지 않았을 때 표시되는 페이지)를 보여줍니다 customErrors
. redirectMode="ResponseRewrite"
부품을 제거하면 제대로 작동합니다.
동일한 서버에서 호스팅되는 다른 사이트에서 동일한 설정을 사용하기 때문에 3.5 SP1이 서버에 설치되어 있다고 확신합니다.
어떤 아이디어?
이면에서 ResponseRewrite
사용 하는 MVC 응용 프로그램에서이 작업을 수행하려는 모든 사람을 위해 주목하는 것이 중요 Server.Transfer
합니다. 따라서은 defaultRedirect
파일 시스템의 합법적 인 파일과 일치해야합니다. 분명히 Server.Transfer
MVC 경로와 호환되지 않으므로 오류 페이지가 컨트롤러 작업에 의해 제공되는 경우 Server.Transfer
/ Error / Whatever를 찾고 파일 시스템에서 찾지 않고 일반 404 오류 페이지를 반환합니다!
나를 위해 완벽하게 작동하는 유일한 방법은 사용자 지정 오류를 끄고 web.config를 통해 iis의 오류 페이지를 교체하는 것입니다. 응답과 함께 올바른 상태 코드를 보내고 mvc를 거치지 않는 이점이 있습니다.
여기에 코드가 있습니다
사용자 지정 오류 끄기
<customErrors mode="Off" />
오류 페이지 교체
<httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="404" subStatusCode="-1" /> <remove statusCode="500" subStatusCode="-1" /> <error statusCode="404" path="Error404.html" responseMode="File" /> <error statusCode="500" path="Error.html" responseMode="File" /> </httpErrors>
노트. responsemode="file"
URL이 파일에 대한 직접 링크 인 경우 사용
정보 : http://tipila.com/tips/use-custom-error-pages-aspnet-mvc
무슨 일이 일어나고 있는지 IIS가 오류 상태 코드를 확인하고 사용자 대신 자체 오류 페이지를 표시합니다. 이 문제를 해결하려면 IIS가이 작업을 수행하지 못하도록 오류 페이지의 코드 뒤에있는 페이지에이를 설정해야합니다.
Response.TrySkipIisCustomErrors = true;
이것은 IIS7 이상에서만 작동하며, 이전 버전의 IIS에서는 오류 페이지 설정을 사용해야합니다.
의존성으로 인해 Server.Transfer
의 내부 구현이 ResponseRewrite
MVC와 호환되지 않는 것 같습니다 .
나는 HTTP 모듈을 사용하여이 기능을 다시 구현하기로 결정 그래서이 그래서, 나에게 눈부신 기능 구멍처럼 보인다 그냥 작동합니다 . 아래의 솔루션을 사용하면 평소처럼 유효한 MVC 경로 (물리적 파일 포함)로 리디렉션하여 오류를 처리 할 수 있습니다.
<customErrors mode="RemoteOnly" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="404.aspx" />
<error statusCode="500" redirect="~/MVCErrorPage" />
</customErrors>
이것은 다음 플랫폼에서 테스트되었습니다.
- 통합 파이프 라인 모드의 MVC4 (IIS Express 8)
- 클래식 모드의 MVC4 (VS Development Server, Cassini)
- 클래식 모드의 MVC4 (IIS6)
namespace Foo.Bar.Modules {
/// <summary>
/// Enables support for CustomErrors ResponseRewrite mode in MVC.
/// </summary>
public class ErrorHandler : IHttpModule {
private HttpContext HttpContext { get { return HttpContext.Current; } }
private CustomErrorsSection CustomErrors { get; set; }
public void Init(HttpApplication application) {
System.Configuration.Configuration configuration = WebConfigurationManager.OpenWebConfiguration("~");
CustomErrors = (CustomErrorsSection)configuration.GetSection("system.web/customErrors");
application.EndRequest += Application_EndRequest;
}
protected void Application_EndRequest(object sender, EventArgs e) {
// only handle rewrite mode, ignore redirect configuration (if it ain't broke don't re-implement it)
if (CustomErrors.RedirectMode == CustomErrorsRedirectMode.ResponseRewrite && HttpContext.IsCustomErrorEnabled) {
int statusCode = HttpContext.Response.StatusCode;
// if this request has thrown an exception then find the real status code
Exception exception = HttpContext.Error;
if (exception != null) {
// set default error status code for application exceptions
statusCode = (int)HttpStatusCode.InternalServerError;
}
HttpException httpException = exception as HttpException;
if (httpException != null) {
statusCode = httpException.GetHttpCode();
}
if ((HttpStatusCode)statusCode != HttpStatusCode.OK) {
Dictionary<int, string> errorPaths = new Dictionary<int, string>();
foreach (CustomError error in CustomErrors.Errors) {
errorPaths.Add(error.StatusCode, error.Redirect);
}
// find a custom error path for this status code
if (errorPaths.Keys.Contains(statusCode)) {
string url = errorPaths[statusCode];
// avoid circular redirects
if (!HttpContext.Request.Url.AbsolutePath.Equals(VirtualPathUtility.ToAbsolute(url))) {
HttpContext.Response.Clear();
HttpContext.Response.TrySkipIisCustomErrors = true;
HttpContext.Server.ClearError();
// do the redirect here
if (HttpRuntime.UsingIntegratedPipeline) {
HttpContext.Server.TransferRequest(url, true);
}
else {
HttpContext.RewritePath(url, false);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext);
}
// return the original status code to the client
// (this won't work in integrated pipleline mode)
HttpContext.Response.StatusCode = statusCode;
}
}
}
}
}
public void Dispose() {
}
}
}
용법
이것을 web.config의 최종 HTTP 모듈로 포함하십시오.
<system.web>
<httpModules>
<add name="ErrorHandler" type="Foo.Bar.Modules.ErrorHandler" />
</httpModules>
</system.web>
<!-- IIS7+ -->
<system.webServer>
<modules>
<add name="ErrorHandler" type="Foo.Bar.Modules.ErrorHandler" />
</modules>
</system.webServer>
이 질문이 약간 오래되었다는 것을 알고 있지만이 작업을 수행하기 위해 정적 파일 일 필요는 없다는 점을 지적해야한다고 생각했습니다.
I ran into a similar thing, and it's just a matter of finding that error in your Error.aspx, in our case it was because the masterpage in use relied on a piece of session data and when ResponseRewrite was set the session is not available to our Error.aspx page.
I haven't worked out yet whether this unavailability of session is due to our specific app config or a "by design" part of ASP.net.
I found that the problem was in Error.aspx. Still can't find what was the actual error in error.aspx that causes the problem.
Changing the page to a static html file solved the problem.
I built an error page in aspx that transfers the query to an ASP.NET MVC controller. You can rewrite the query to this aspx page and it will transfer the query to your custom controller.
protected void Page_Load(object sender, EventArgs e)
{
//Get status code
var queryStatusCode = Request.QueryString.Get("code");
int statusCode;
if (!int.TryParse(queryStatusCode, out statusCode))
{
var lastError = Server.GetLastError();
HttpException ex = lastError as HttpException;
statusCode = ex == null ? 500 : ex.GetHttpCode();
}
Response.StatusCode = statusCode;
// Execute a route
RouteData routeData = new RouteData();
string controllerName = Request.QueryString.Get("controller") ?? "Errors";
routeData.Values.Add("controller", controllerName);
routeData.Values.Add("action", Request.QueryString.Get("action") ?? "Index");
var requestContext = new RequestContext(new HttpContextWrapper(Context), routeData);
IController controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestContext, controllerName);
controller.Execute(requestContext);
}
Find more details here : https://stackoverflow.com/a/27354140/143503
In my particular case, my error page had a master page that had a user control that tried to use Session. If Session isn't available, you get an HttpException: "Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive." Easiest fix is to switch to static html, second easiest fix is to use a simpler error page, hardest fix is to make incredibly sure that your error page makes no assumptions anywhere (like that Session won't throw an exception, for example) and can't possibly error out.
I have found out that if you use redirectMode="ResponseRewrite" then you need to add something in the rewrite area of the web.config file. Problem is when your site is broken! You can't URL rewrite as your site can't call the "virtual.aspx" that handles your rewrite!
'development' 카테고리의 다른 글
Android 리소스와 리소스 ID 간의 매핑은 어떻게 작동합니까? (0) | 2020.10.28 |
---|---|
iframe에 대한 jQuery Force set src 속성 (0) | 2020.10.28 |
Javascript에서 NodeList를 배열로 변환하는 가장 좋은 방법은 무엇입니까? (0) | 2020.10.28 |
AngularJS에서 페이지 맨 위로 스크롤하는 방법은 무엇입니까? (0) | 2020.10.28 |
jQuery를 배우기 전에 JavaScript를 배우는 것이 좋은 생각입니까? (0) | 2020.10.28 |