ロジックが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