これは、MVC ツールを使用して、不適切なコントローラー名、不適切なルート名、およびアクション メソッド内に適合するその他の基準への要求を処理できる別の方法です。Server.Transfer
個人的には、302 / 200 リダイレクトを行い、Razor ビューを使用したResponseRewrite () をサポートしていないため、できるだけ多くの web.config 設定を避けることを好みます。SEO の理由から、カスタム エラー ページで 404 を返したいと思います。
これらのいくつかは、上記の cottsak の手法を新たに取り入れたものです。
このソリューションでは、代わりに MVC 3 エラー フィルターを優先する最小限の web.config 設定も使用します。
使用法
アクションまたはカスタム ActionFilterAttribute から HttpException をスローするだけです。
Throw New HttpException(HttpStatusCode.NotFound, "[Custom Exception Message Here]")
ステップ1
次の設定を web.config に追加します。これは、MVC の HandleErrorAttribute を使用するために必要です。
<customErrors mode="On" redirectMode="ResponseRedirect" />
ステップ2
HTTP エラーを除いて、MVC フレームワークの HandleErrorAttribute と同様のカスタム HandleHttpErrorAttribute を追加します。
<AttributeUsage(AttributeTargets.All, AllowMultiple:=True)>
Public Class HandleHttpErrorAttribute
Inherits FilterAttribute
Implements IExceptionFilter
Private Const m_DefaultViewFormat As String = "ErrorHttp{0}"
Private m_HttpCode As HttpStatusCode
Private m_Master As String
Private m_View As String
Public Property HttpCode As HttpStatusCode
Get
If m_HttpCode = 0 Then
Return HttpStatusCode.NotFound
End If
Return m_HttpCode
End Get
Set(value As HttpStatusCode)
m_HttpCode = value
End Set
End Property
Public Property Master As String
Get
Return If(m_Master, String.Empty)
End Get
Set(value As String)
m_Master = value
End Set
End Property
Public Property View As String
Get
If String.IsNullOrEmpty(m_View) Then
Return String.Format(m_DefaultViewFormat, Me.HttpCode)
End If
Return m_View
End Get
Set(value As String)
m_View = value
End Set
End Property
Public Sub OnException(filterContext As System.Web.Mvc.ExceptionContext) Implements System.Web.Mvc.IExceptionFilter.OnException
If filterContext Is Nothing Then Throw New ArgumentException("filterContext")
If filterContext.IsChildAction Then
Return
End If
If filterContext.ExceptionHandled OrElse Not filterContext.HttpContext.IsCustomErrorEnabled Then
Return
End If
Dim ex As HttpException = TryCast(filterContext.Exception, HttpException)
If ex Is Nothing OrElse ex.GetHttpCode = HttpStatusCode.InternalServerError Then
Return
End If
If ex.GetHttpCode <> Me.HttpCode Then
Return
End If
Dim controllerName As String = filterContext.RouteData.Values("controller")
Dim actionName As String = filterContext.RouteData.Values("action")
Dim model As New HandleErrorInfo(filterContext.Exception, controllerName, actionName)
filterContext.Result = New ViewResult With {
.ViewName = Me.View,
.MasterName = Me.Master,
.ViewData = New ViewDataDictionary(Of HandleErrorInfo)(model),
.TempData = filterContext.Controller.TempData
}
filterContext.ExceptionHandled = True
filterContext.HttpContext.Response.Clear()
filterContext.HttpContext.Response.StatusCode = Me.HttpCode
filterContext.HttpContext.Response.TrySkipIisCustomErrors = True
End Sub
End Class
ステップ 3
の GlobalFilterCollection ( GlobalFilters.Filters
) にフィルタを追加しGlobal.asax
ます。この例では、すべての InternalServerError (500) エラーをエラー共有ビュー ( Views/Shared/Error.vbhtml
) にルーティングします。NotFound (404) エラーは、共有ビューの ErrorHttp404.vbhtml にも送信されます。ここに 401 エラーを追加して、追加の HTTP エラー コードに対してこれを拡張する方法を示します。これらは共有ビューである必要があり、すべてSystem.Web.Mvc.HandleErrorInfo
オブジェクトをモデルとして使用することに注意してください。
filters.Add(New HandleHttpErrorAttribute With {.View = "ErrorHttp401", .HttpCode = HttpStatusCode.Unauthorized})
filters.Add(New HandleHttpErrorAttribute With {.View = "ErrorHttp404", .HttpCode = HttpStatusCode.NotFound})
filters.Add(New HandleErrorAttribute With {.View = "Error"})
ステップ 4
基本コントローラー クラスを作成し、コントローラーでそれを継承します。この手順により、不明なアクション名を処理し、HTTP 404 エラーを HandleHttpErrorAttribute に発生させることができます。
Public Class BaseController
Inherits System.Web.Mvc.Controller
Protected Overrides Sub HandleUnknownAction(actionName As String)
Me.ActionInvoker.InvokeAction(Me.ControllerContext, "Unknown")
End Sub
Public Function Unknown() As ActionResult
Throw New HttpException(HttpStatusCode.NotFound, "The specified controller or action does not exist.")
Return New EmptyResult
End Function
End Class
ステップ 5
ControllerFactory オーバーライドを作成し、Application_Start の Global.asax ファイルでオーバーライドします。この手順により、無効なコントローラー名が指定された場合に HTTP 404 例外を発生させることができます。
Public Class MyControllerFactory
Inherits DefaultControllerFactory
Protected Overrides Function GetControllerInstance(requestContext As System.Web.Routing.RequestContext, controllerType As System.Type) As System.Web.Mvc.IController
Try
Return MyBase.GetControllerInstance(requestContext, controllerType)
Catch ex As HttpException
Return DependencyResolver.Current.GetService(Of BaseController)()
End Try
End Function
End Class
'In Global.asax.vb Application_Start:
controllerBuilder.Current.SetControllerFactory(New MyControllerFactory)
ステップ 6
BaseController Unknown アクションの RoutTable.Routes に特別なルートを含めます。これは、ユーザーが不明なコントローラーまたは不明なアクションにアクセスした場合に 404 を発生させるのに役立ちます。
'BaseController
routes.MapRoute( _
"Unknown", "BaseController/{action}/{id}", _
New With {.controller = "BaseController", .action = "Unknown", .id = UrlParameter.Optional} _
)
概要
この例では、MVC フレームワークを使用して、フィルター属性と共有エラー ビューを使用してリダイレクトせずに 404 Http エラー コードをブラウザーに返す方法を示しました。また、無効なコントローラー名とアクション名が指定された場合に、同じカスタム エラー ページを表示することも示しています。
無効なコントローラー名、アクション名、および Home/TriggerNotFound アクションから発生したカスタム 404 のスクリーンショットを追加します (=) を投稿するのに十分な投票が得られた場合。このソリューションを使用して次の URL にアクセスすると、Fiddler は 404 メッセージを返します。
/InvalidController
/Home/InvalidRoute
/InvalidController/InvalidRoute
/Home/TriggerNotFound
上記の cottsak の投稿とこれらの記事は参考になりました。