NerdDinnerアプリケーションに精通しているかどうかはわかりません。メソッドGetRuleViolations()とプロパティIsValidをDinnerオブジェクトに追加します。オブジェクトが保存されると、オブジェクトが有効かどうかがチェックされます。そうでない場合は、例外がスローされます。例外がキャッチされたコントローラでは、ViewDataのModelStateがルール違反で満たされ、ビューが再表示されます。 Html.Validationヘルパーはエラーを強調表示します。ASP.NET MVC:例外フィルタ用のViewDataを作成する方法
私がしたいのは、(MVCフレームワークの一部である)HandleExceptionAttributeと同様のHandleRuleViolationExceptionAttributeを作成することです。問題は、この属性がViewのModelstateを再投入する必要があることです。
ビューは、そのモデルに任意のオブジェクト型を持つことができます。 RuleViolationExceptionをスローするコードは、RuleViolationException.ObjectをViewのモデルに設定します。
私はMVCのソースコードでHandleExceptionAttributeのコードを見上げて、それを修正:
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method, _
Inherited:=True, AllowMultiple:=False)> _
Public Class HandleRuleViolationExceptionAttribute
Inherits FilterAttribute
Implements IExceptionFilter
Private m_View As String
Private m_MasterPage As String
Public Property View() As String
Get
Return m_View
End Get
Set(ByVal value As String)
m_View = value
End Set
End Property
Public Property MasterPage() As String
Get
Return If(m_MasterPage, String.Empty)
End Get
Set(ByVal value As String)
m_MasterPage = value
End Set
End Property
Public Sub OnException(ByVal filterContext As System.Web.Mvc.ExceptionContext) _
Implements System.Web.Mvc.IExceptionFilter.OnException
If filterContext Is Nothing Then
Throw New ArgumentException("filterContext is null")
End If
'Ignore if the error is already handled.
If filterContext.ExceptionHandled Then Return
'Handle only ObjectIsInvalidExceptions.
If Not TypeOf filterContext.Exception Is ObjectIsInvalidException Then
Return
End If
Dim ex As ObjectIsInvalidException = DirectCast(filterContext.Exception, ObjectIsInvalidException)
'If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
'ignore it.
If (New HttpException(Nothing, ex).GetHttpCode()) <> 500 Then Return
Dim actionName As String = CStr(filterContext.RouteData.Values("action"))
Dim viewName As String = If(String.IsNullOrEmpty(View), actionName, View)
Dim viewData = filterContext.Controller.ViewData
viewData.Model = ex.Object
For Each item As String In filterContext.HttpContext.Request.Form.Keys
viewData.Add(item, filterContext.HttpContext.Request.Form.Item(item))
Next
For Each ruleViolation In ex.Object.GetRuleViolations()
viewData.ModelState.AddModelError(ruleViolation.PropertyName, ruleViolation.ErrorMessage)
Next
filterContext.Result = New ViewResult() With _
{ _
.ViewName = viewName, _
.MasterName = MasterPage, _
.ViewData = viewData, _
.TempData = filterContext.Controller.TempData _
}
filterContext.ExceptionHandled = True
filterContext.HttpContext.Response.Clear()
filterContext.HttpContext.Response.StatusCode = 500
'Certain versions of IIS will sometimes use their own error page when
'they detect a server error. Setting this property indicates that we
'want it to try to render ASP.NET MVC's error page instead.
filterContext.HttpContext.Response.TrySkipIisCustomErrors = True
End Sub
End Class
私はリクエストのフォームキーを反復ビューのモデルを記入し、ViewDataをするキーとその値を追加するにはインスタンス。それは今では機能しますが、私はこれがそれを行う方法だとは思わない。
コントローラのアクションメソッドでは、モデルをUpdateModelメソッドで更新できました。これは、viewStatesのModelStateも更新します。私は、更新する必要があるプロパティ名を持つ文字列の配列を含めることができます。または、モデルをActionパラメータとして使用する場合、バインド属性を使用して一部のプロパティを除外または除外できます(作成アクション上記)。私の方法はこれに固執せず、セキュリティ上の問題が発生する可能性があります。
コントローラのUpdateModelメソッドと同様に機能するOnExceptionメソッドのViewDataオブジェクトを構築するより良い方法はありますか? ExceptionHandlerAttributeからUpdateModelメソッドを呼び出す方法はありますか?
おかげで、 ギヨームHanique
返信いただきありがとうございます! 属性には実際に設定可能なビュープロパティがありますが、設定できない場合は、アクション名がビュー名として使用されます。 filterContext.Controller.UpdateModel filterContext.Controllerは、UpdateModelメソッドを持たないControllerBase型です。他のアイデア? 実際のControllerインスタンスをこの属性(コントローラのアクションのthis/Me)に渡してモデルを更新することができますか? –
良い点。私はそれを逃した。コードを振り返ってみると、私は実際にこれをここで行うために必要な作業はほとんどないと思います。 viewData.Modelをex.Objectに設定することで、同じことが達成されます。私はex.Objectからすべてのフォームデータを取得すると思いますか?そうでないかもしれない。 –
私はあきらめます。私は、UpdateModelが呼び出すメソッドであるかどうか分からない。たとえそれがあっても、私はどのように考え出すことができません。ビューのModelプロパティを設定するときに誰かがModelStateを更新する方法を知っていますか? –