0

ロジックがMVCアプリのどこに行くのかについていくつか質問があります。

これはコントローラーのサンプルアクションであり、これがロジックが多すぎるかどうか疑問に思っていました。ロジックが多すぎる場合は、他にどこに配置しますか。

参考までに-Manager一種のサービスタイプレイヤーであり、BOをDTO / ViewModelsに変換し、BLを実行する別のレイヤーに変換します。

Public Function ChangeClaim(model As ChangeClaimViewModel) As ActionResult
        Manager.SetClaimNumber(model.ClaimNumber)

        Dim securityToken = Manager.ClaimSecurityToken

        If (securityToken.ValidClaim) Then
            Session("ClaimNumber") = model.ClaimNumber
            If (Not securityToken.ConflictAccess) Then
                ModelState.AddModelError("ClaimNumber", "You do not have access to this claim.")
            End If
        Else
            ModelState.AddModelError("ClaimNumber", "Invalid claim number.")
        End If

        If (Not ModelState.IsValid) Then
            Return View(Manager.GetViewModel())
        End If

        If (model.URL.Contains("ChangeClaim") OrElse model.URL.Contains("EnterClaim")) Then
            model.URL = Url.Action("Index", "Home")
        End If

        Return Redirect(model.URL)

    End Function

boolまた、ビューでそのようなロジックを実行するために使用するViewModelをぶら下げても大丈夫だと思いますか?

@if (Model.HasExposureAccess)
    {
        <li><a href="#tab-pane-2">@Model.Labels.Reimbursements</a></li>
    }

改善のための他の提案はありますか?

ああ、VBとC#の組み合わせで申し訳ありませんが、私が働いているショップはVBのビューを除いてすべてを行っており、C#のビューを実行するために戦わなければなりませんでした!! ??

編集#1

ですから、If (securityToken.ValidClaim) Then私はあなたにプロセスを実行し、何か提案があるかどうかを確認するために最善を尽くします。

ユーザーがクレーム番号を変更しようとすると、モデルに取り込まれ、Manager.SetClaimメソッドに渡されます(マネージャーは、既存のBOフレームワークを使用できるようにするために作成した一種のサービスレイヤーであり、笑わないでください)は、CSLA.NET V1の大幅に変更されたバージョンであり、BLとDALがすべてオブジェクト内に存在する限り、非常に緊密に結合されたオブジェクトです。私の選択ではありませんが、何をしますか:))有効なクレームであり、ユーザーはそれにアクセスできます。私はレイヤーを可能な限り分離しておくために一生懸命努力しています:

1)MVCアプリ
2)アプリケーションマネージャー
3)既存のBOF

意味がありましたか?

編集#2

だから私はコントローラーアクションからのロジックを次のようなアクションフィルターに入れました:

Public Class ValidateClaimAttribute
Inherits ActionFilterAttribute

Public Overrides Sub OnActionExecuting(filterContext As System.Web.Mvc.ActionExecutingContext)
    MyBase.OnActionExecuting(filterContext)

    Dim model As ChangeClaimViewModel = CType(filterContext.ActionParameters("model"), ChangeClaimViewModel)
    Dim manager As IInjuredWorkerManager = DependencyResolver.Current.GetService(Of IInjuredWorkerManager)()
    Dim securityToken = manager.ClaimSecurityToken

    manager.SetClaimNumber(model.ClaimNumber)

    If (securityToken.ValidClaim) Then
        filterContext.HttpContext.Session("ClaimNumber") = model.ClaimNumber
        If (Not securityToken.ConflictAccess) Then
            filterContext.Controller.ViewData.ModelState.AddModelError("ClaimNumber", "You do not have access to this claim.")
        End If
    Else
        filterContext.Controller.ViewData.ModelState.AddModelError("ClaimNumber", "Invalid claim number.")
    End If

End Sub
End Class

<ValidateClaim()>
    Public Function ChangeClaim(model As ChangeClaimViewModel) As ActionResult
        If (Not ModelState.IsValid) Then
            Return View(Manager.GetViewModel())
        End If

        If (model.URL.Contains("ChangeClaim") OrElse model.URL.Contains("EnterClaim")) Then
            model.URL = Url.Action("Index", "Home")
        End If

        Return Redirect(model.URL)

    End Function

これは、これを行う正しい方法のように見えますか?

編集#3 それで、私はこれにさらに最適化しました:

<ValidateClaim()>
    Public Function ChangeClaim(model As ChangeClaimViewModel) As ActionResult
        If (Not ModelState.IsValid) Then
            Return View(Manager.GetViewModel())
        End If

        Return New MyRedirect(model.URL)

    End Function
    Public Class ValidateClaimAttribute
Inherits ActionFilterAttribute

Public Overrides Sub OnActionExecuting(filterContext As System.Web.Mvc.ActionExecutingContext)
    MyBase.OnActionExecuting(filterContext)

    Dim model As ChangeClaimViewModel = CType(filterContext.ActionParameters("model"), ChangeClaimViewModel)
    Dim manager As IInjuredWorkerManager = DependencyResolver.Current.GetService(Of IInjuredWorkerManager)()
    Dim securityToken = manager.ClaimSecurityToken

    manager.SetClaimNumber(model.ClaimNumber)

    If (securityToken.ValidClaim) Then
        filterContext.HttpContext.Session("ClaimNumber") = model.ClaimNumber
        If (Not securityToken.ConflictAccess) Then
            filterContext.Controller.ViewData.ModelState.AddModelError("ClaimNumber", "You do not have access to this claim.")
        End If
    Else
        filterContext.Controller.ViewData.ModelState.AddModelError("ClaimNumber", "Invalid claim number.")
    End If

End Sub

End Class

Public Class MyRedirect
Inherits ActionResult

Private _url As String

Public Sub New(url As String)
    _url = url
End Sub

Public Overrides Sub ExecuteResult(context As System.Web.Mvc.ControllerContext)
    Dim urlHelper As New UrlHelper(context.RequestContext)

    If (_url.Contains("ChangeClaim") OrElse _url.Contains("EnterClaim")) Then
        _url = urlHelper.Action("Index", "Home")
    End If

    context.HttpContext.Response.Redirect(_url)
End Sub
End Class

完全なコントローラーコード:

Imports System.Web.Mvc
Imports System.Security.Principal
Imports Telerik.Web.Mvc
Imports System.Globalization

Namespace Controllers
<HandleException(View:="Error")>
<OutputCache(Duration:=0)>
Public MustInherit Class InjuredWorkerController
    Inherits SAIF.Web.Mvc.Framework.Controllers.ContextController



    Public Property Manager As IInjuredWorkerManager

    Public Sub New(manager As IInjuredWorkerManager)
        _Manager = manager
        _Manager.ValidationDictonary = New ModelStateWrapper(ModelState)


    End Sub

    <ValidateClaim()>
    Public Function ChangeClaim(model As ChangeClaimViewModel) As ActionResult
        If (Not ModelState.IsValid) Then
            Return View(Manager.GetViewModel())
        End If

        Return New MyRedirect(model.URL)

    End Function

    Public Function SetCulture(culture As String, returnUrl As String) As ActionResult
        Response.Cookies.Add(New HttpCookie("culture") With {
                             .Value = culture,
                             .Expires = DateTime.Now.AddYears(1)
                         })

        Return Redirect(returnUrl)

    End Function

    Protected Overrides Sub ExecuteCore()
        Dim cultureName = "en-US"
        Dim cultureCookie = Request.Cookies("culture")

        If (cultureCookie IsNot Nothing) Then
            cultureName = Request.Cookies("culture").Value
        End If

        Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(cultureName)
        Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(cultureName)

        MyBase.ExecuteCore()
    End Sub

    Protected Overrides Sub OnActionExecuting(filterContext As System.Web.Mvc.ActionExecutingContext)
        MyBase.OnActionExecuting(filterContext)

        Dim controller = filterContext.RouteData.Values("controller").ToString
        Dim action = filterContext.RouteData.Values("action").ToString

        If (action.ToLower = "enterclaim" OrElse action.ToLower = "changeclaim") Then
            Return
        Else
            Dim claimNumber As String = String.Empty
            Dim workerID As Decimal

            If (Session("ClaimNumber") IsNot Nothing) Then
                claimNumber = Session("ClaimNumber").ToString
            End If

            If (Session("WorkerID") IsNot Nothing) Then
                workerID = CDec(Session("WorkerID"))
            End If

            If (String.IsNullOrEmpty(claimNumber)) Then
                If (workerID = 0) Then
                    If (Manager.IsExternalUser) Then
                        workerID = Manager.GetWorkerIdByDomainUser
                        claimNumber = Manager.GetMostRecentClaimNumber(workerID)
                    Else
                        filterContext.Result = New RedirectResult("/MyClaim/Home/EnterClaim")
                    End If
                End If
            End If

            Manager.SetClaimNumber(claimNumber)

        End If

    End Sub

    Public Function SendMessage(<Bind(prefix:="SendMessage")> model As IWSendMessageViewModel) As ActionResult
        Manager.SendAdjusterEmail(model.AdjusterEmail, model.PersonEmail, "IW Contact Message", model.Message, model.SendCopyToSender)
        Return Json(New With {.message = "Success"}, "application/json")
    End Function

End Class

End Namespace
4

1 に答える 1

2

これは、コントローラーのアクションには間違いなく多すぎます。のようなものは、コントローラーアクションを装飾する必要がIf (Not securityToken.ConflictAccess)あるカスタム属性に入れる必要があります。カスタム検証属性に入る、またはモデルのFVバリデーターでFluentValidation.NET(これを強くお勧めします)を使用している場合AuthorizeなどですModelState.AddModelError("ClaimNumber", "Invalid claim number.")

このようなもの:

If (model.URL.Contains("ChangeClaim") OrElse model.URL.Contains("EnterClaim")) Then
    model.URL = Url.Action("Index", "Home")
End If

あなたが返すカスタムアクションの結果に入る可能性があります。

ビューの条件付きロジックに関する限り、問題ありません。ビューモデルのプロパティを使用して、特定のUI要素を表示/非表示にすることができます。ユーザーからリンクを非表示にしたからといって、悪意のあるユーザーがリクエストを偽造できず、コントローラーを呼び出すことができるわけではないため、対応するコントローラーアクションで(カスタムの承認属性を介して)適切な承認を行う必要があります。アクション。

于 2012-07-26T15:30:27.130 に答える