ASP.NET 사용자 지정 404에서 404 찾을 수 없음 대신 200 OK 반환
내 사이트에서 Google 웹 마스터 도구를 설정하려고 시도한 후 내 사용자 지정 ASP.NET 404 페이지가 404 상태 코드를 반환하지 않는 것을 발견했습니다. 올바른 사용자 정의 페이지를 표시하고 모든 것이 정상이라고 브라우저에 알 렸습니다. 이것은 soft 404 또는 false 404로 간주됩니다. Google은 이것을 좋아하지 않습니다. 그래서 문제에 대한 많은 기사를 찾았지만 원하는 솔루션이 작동하지 않는 것 같습니다.
내가 작업하고 싶은 해결책은 사용자 지정 404 페이지의 Page_Load 메서드 뒤에있는 코드에 다음 두 줄을 추가하는 것입니다.
Response.Status = "404 Not Found";
Response.StatusCode = 404;
이것은 작동하지 않습니다. 페이지는 여전히 200 OK를 반환합니다. 그러나 다음 코드를 디자인 코드에 하드 코딩하면 제대로 작동한다는 것을 알았습니다.
<asp:Content ID="ContentMain" ContentPlaceHolderID="ContentPlaceHolderMaster" runat="server">
<%
Response.Status = "404 Not Found";
Response.StatusCode = 404;
%>
... Much more code ...
</asp:content>
페이지가 마스터 페이지를 사용하고 있습니다. 그리고 내 web.config에서 사용자 지정 오류 페이지를 구성하고 있습니다. 나는 정말로 차라리 코드 숨김 옵션을 사용하고 싶지만 디자인 / 레이아웃에 해킹 인라인 코드를 넣지 않고는 작동하지 않는 것 같습니다.
해결책:
문제는 마스터 페이지의 사용이었습니다. 페이지 수명주기 후반에 상태 코드를 설정하여 작동하도록했습니다. 분명히 마스터 페이지의 렌더링이이를 재설정했기 때문에 렌더링 메서드를 무시하고 렌더링이 완료된 후에 설정했습니다.
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
Response.StatusCode = 404;
}
마스터 페이지가 상태를 설정하는시기를 정확히 알기 위해 더 많은 작업을 수행 할 수 있지만, 그 상태는 귀하에게 맡기겠습니다.
원본 게시물 :
테스트 웹 앱이 제대로 작동하도록 할 수 있었는데, 적어도 사용자 지정 오류 페이지를 표시하고 404 상태 코드를 반환했습니다. 앱에 어떤 문제가 있는지 말씀 드릴 수는 없지만 내가 한 일은 말할 수 있습니다.
1) 사용자 지정 오류에 대한 web.config 편집 :
<customErrors mode="On"> <error statusCode="404" redirect="404.aspx"/> </customErrors>
2) 404.aspx 페이지를 추가하고 상태 코드를 404로 설정했습니다.
public partial class _04 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Response.StatusCode = 404; } }
Asp.Net에 의해 처리되고 존재하지 않는 페이지 확장으로 이동하면 내 피들러 로그에 404가 명확하게 표시되며 다음은 헤더입니다.
HTTP/1.1 404 Not Found Server: Microsoft-IIS/5.1 Date: Sun, 07 Dec 2008 06:04:13 GMT X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private Content-Type: text/html; charset=utf-8 Content-Length: 533
이제 htm 파일과 같이 Asp.Net에서 처리되지 않는 페이지로 이동하면 사용자 지정 페이지가 표시되지 않고 IIS에서 구성한 404가 표시됩니다.
다음은 귀하와 귀하의 문제에 도움이 될 수있는 몇 가지 세부 사항에 대한 게시물입니다. 내 테스트는 새 페이지로 리디렉션을 수행하므로 요청 된 파일의 URL이 거의 손실됩니다 (쿼리 문자열 제외). .
Google 404 및 .NET 사용자 지정 오류 페이지
헤더 스파이 응답 :
HTTP/1.1 404 Not Found
Date: Sun, 07 Dec 2008 06:21:20 GMT
비슷한 문제가 발생하여 사용자 지정 페이지를 404 (ASPX)로 표시하고 로컬 호스트에서 제대로 작동했지만 원격 방문자가 연결하자마자 일반 IIS 404를 가져옵니다.
이에 대한 해결책은
Response.TrySkipIisCustomErrors = true;
Response.StatusCode를 변경하기 전에.
Rick Strahl http://www.west-wind.com/weblog/posts/745738.aspx 를 통해 찾았습니다 .
IIS 7 솔루션은 다음을 web.config 파일에 추가하는 것입니다.
<system.webServer>
<httpErrors existingResponse="Replace">
<remove statusCode="500" subStatusCode="-1" />
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="404.htm" responseMode="File" />
<error statusCode="500" prefixLanguageFilePath="" path="500.htm" responseMode="File" />
</httpErrors>
</system.webServer>
http://forums.asp.net/t/1563128.aspx/1
렌더링을 건너 뛰려면 Response.End ()를 호출 해보십시오 ...
Response.Status = "404 Not Found";
Response.StatusCode = 404;
Response.End();
return;
많은 테스트와 문제 해결 후 특정 호스팅 공급자가 반환 코드를 방해 할 수있는 것으로 보입니다. 콘텐츠에 "해킹"을 적용하여이 문제를 해결할 수있었습니다.
<%
// This code is required for host that do special 404 handling...
Response.Status = "404 Not Found";
Response.StatusCode = 404;
%>
이렇게하면 페이지가 무엇이든지 올바른 반환 코드를 반환 할 수 있습니다.
.NET 3.5를 사용하는 asp.net 웹 양식에서 다음 설정을 사용하여이 문제를 해결할 수있었습니다.
내가 구현 한 패턴은 헤더에 올바른 HTTP 상태 코드로 모든 시나리오를 처리하기 위해 직접 작성 했으므로 web.config에서 .NET의 사용자 지정 리디렉션 솔루션을 우회합니다.
먼저 web.config의 customErrors 섹션은 다음과 같습니다.
<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" />
이 설정은 CustomErrors 모드가 on으로 설정되어 있는지 확인하고, 이는 나중에 필요로하는 설정이며 error.htm의 defaultRedirect에 대해 all-else-fails 옵션을 제공합니다. 이것은 특정 오류에 대한 핸들러가 없거나 끊어진 데이터베이스 연결 라인을 따라 무언가가있을 때 유용합니다.
둘째, 다음은 글로벌 asax 오류 이벤트입니다.
protected void Application_Error(object sender, EventArgs e)
{
HandleError();
}
private void HandleError()
{
var exception = Server.GetLastError();
if (exception == null) return;
var baseException = exception.GetBaseException();
bool errorHandled = _applicationErrorHandler.HandleError(baseException);
if (!errorHandled) return;
var lastError = Server.GetLastError();
if (null != lastError && HttpContext.Current.IsCustomErrorEnabled)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(lastError.GetBaseException());
Server.ClearError();
}
}
This code is passing off the responsibility of handling the error to another class. If the error isn't handled and CustomErrors is turned on, that means we've got a case where we're on production and somehow an error hasn't been handled. We'll clear it here in order to prevent the user from seeing it, but log it in Elmah so we know what's going on.
The applicationErrorHandler class looks like this:
public bool HandleError(Exception exception)
{
if (exception == null) return false;
var baseException = exception.GetBaseException();
Elmah.ErrorSignal.FromCurrentContext().Raise(baseException);
if (!HttpContext.Current.IsCustomErrorEnabled) return false;
try
{
var behavior = _responseBehaviorFactory.GetBehavior(exception);
if (behavior != null)
{
behavior.ExecuteRedirect();
return true;
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return false;
}
This class essentially uses the command pattern to locate the appropriate error handler for the type of error that's issued. It's important to use Exception.GetBaseException() at this level, because almost every error will be wrapped in a higher-level exception. For example, doing "throw new System.Exception()" from any aspx page will result in an HttpUnhandledException being received at this level, not a System.Exception.
The "factory" code is simple and looks like this:
public ResponseBehaviorFactory()
{
_behaviors = new Dictionary<Type, Func<IResponseBehavior>>
{
{typeof(StoreException), () => new Found302StoreResponseBehavior()},
{typeof(HttpUnhandledException), () => new HttpExceptionResponseBehavior()},
{typeof(HttpException), () => new HttpExceptionResponseBehavior()},
{typeof(Exception), () => new Found302DefaultResponseBehavior()}
};
}
public IResponseBehavior GetBehavior(Exception exception)
{
if (exception == null) throw new ArgumentNullException("exception");
Func<IResponseBehavior> behavior;
bool tryGetValue = _behaviors.TryGetValue(exception.GetType(), out behavior);
//default value here:
if (!tryGetValue)
_behaviors.TryGetValue(typeof(Exception), out behavior);
if (behavior == null)
Elmah.ErrorSignal.FromCurrentContext().Raise(
new Exception(
"Danger! No Behavior defined for this Exception, therefore the user might have received a yellow screen of death!",
exception));
return behavior();
}
In the end, I've got an extensible error handling scheme setup. In each one of the "behaviors" that is defined, I have a custom implementation for the type of error. For example, a Http exception will be inspected for the status code and handled appropriately. A 404 status code will require a Server.Transfer instead of a Request.Redirect, along with the appropriate status code written in the header.
Hope this helps.
You can use the below code:
Response.TrySkipIisCustomErrors = True
Response.Status = "404 Not Found"
Response.AddHeader("Location", "{your-path-to-your-404-page}")
'developer tip' 카테고리의 다른 글
명령 줄을 애니메이션하는 방법은 무엇입니까? (0) | 2020.10.10 |
---|---|
Visual Studio 프로젝트의 모든 파일을 UTF-8로 저장 (0) | 2020.10.10 |
Select Top 100 %를 사용하는 이유는 무엇입니까? (0) | 2020.10.10 |
django-celery로 단위 테스트? (0) | 2020.10.10 |
init-param 및 context-param (0) | 2020.10.10 |