У меня есть приложение ASP.NET MVC 2, в котором я создаю фильтр пользовательского действия. Этот фильтр находится на контроллерах в приложении и проверяет от базы данных, в настоящее время ли та функция доступна.
Public Overrides Sub OnActionExecuting(ByVal filterContext As System.Web.Mvc.ActionExecutingContext)
Try
' Check controller name against database.
Dim controllerName = filterContext.Controller.GetType().Name
controllerName = controllerName.Remove(controllerName.Length - 10)
' Look up availability.
Dim available As Boolean = _coreService.GetControllerAvailability(controllerName)
If Not available Then
' Redirect to unavailable notice.
filterContext.Result = New RedirectResult("/Home/Unavailable/")
End If
Catch ex As Exception
_eventLogger.LogWarning(ex, EventLogEntryType.Error)
Throw
End Try
End Sub
Моя проблема состоит в том, что в зависимости от действия, которое требовали, я должен перенаправить пользователя к действию, которое возвращает или представление, частичные представления или JSON.
Учитывая ActionExecutingContext я могу узнать, каков тип возврата первоначально требуемого действия?
Править:
Хорошо, я становлюсь ближе, но имею другую проблему.
Public Overrides Sub OnActionExecuting(ByVal filterContext As System.Web.Mvc.ActionExecutingContext)
Try
' Check controller name against database.
Dim controllerName = filterContext.Controller.GetType().Name
Dim shortName = controllerName.Remove(controllerName.Length - 10)
' Look up availability.
Dim available As Boolean = _coreService.GetControllerAvailability(shortName)
If Not available Then
' find out what type is expected to be returned
Dim actionName As String = filterContext.ActionDescriptor.ActionName
Dim controllerType = Type.GetType("Attenda.Stargate.Web." & controllerName)
Dim actionMethodInfo = controllerType.GetMethod(actionName)
Dim actionReturnType = actionMethodInfo.ReturnType.Name
Select Case actionReturnType
Case "PartialViewResult"
filterContext.Result = New RedirectResult("/Home/UnavailablePartial/")
Case "JsonResult"
filterContext.Result = New RedirectResult("/Home/UnavailableJson/")
Case Else
filterContext.Result = New RedirectResult("/Home/Unavailable/")
End Select
End If
Catch ex As Exception
_eventLogger.LogWarning(ex, EventLogEntryType.Error)
Throw
End Try
End Sub
Я могу использовать отражение для нахождения типа возврата метода действия. Моя проблема состоит в том, если у меня есть следующие методы на контроллере:
Public Function Create() As ViewResult
Return View()
End Function
<AcceptVerbs(HttpVerbs.Post)>
Public Function Create(values as FormCollection) As ViewResult
' Do stuff here
End Function
Я бросил AmbiguousMatchException.
С информацией я имею в методе OnActionExecuting, имеет ли так или иначе то, чтобы быть более точным с определением перегрузки, которую называют?
Хорошо, это решение, которое я придумал.
Public Overrides Sub OnActionExecuting(ByVal filterContext As System.Web.Mvc.ActionExecutingContext)
Try
' Check controller name against database.
Dim controllerName = filterContext.Controller.GetType().Name
Dim shortName = controllerName.Remove(controllerName.Length - 10)
' Look up availability.
Dim available As Boolean = _coreService.GetControllerAvailability(shortName)
If Not available Then
' find out what type is expected to be returned
Dim actionName As String = filterContext.ActionDescriptor.ActionName
Dim controllerType = Type.GetType("Attenda.Stargate.Web." & controllerName)
Dim actionMethodInfo As MethodInfo
Try
actionMethodInfo = controllerType.GetMethod(actionName)
Catch ex As AmbiguousMatchException
' Try to find a match using the parameters passed through
Dim actionParams = filterContext.ActionParameters
Dim paramTypes As New List(Of Type)
For Each p In actionParams
paramTypes.Add(p.Value.GetType())
Next
actionMethodInfo = controllerType.GetMethod(actionName, paramTypes.ToArray)
End Try
Dim actionReturnType = actionMethodInfo.ReturnType.Name
Select Case actionReturnType
Case "PartialViewResult"
filterContext.Result = New RedirectResult("/Home/UnavailablePartial/")
Case "JsonResult"
filterContext.Result = New RedirectResult("/Home/UnavailableJson/")
Case Else
filterContext.Result = New RedirectResult("/Home/Unavailable/")
End Select
End If
Catch ex As Exception
_eventLogger.LogWarning(ex, EventLogEntryType.Error)
Throw
End Try
End Sub
Если вызов Type.GetMethod (string) не может идентифицировать запрошенный метод, я беру коллекцию параметров из коллекции ActionExecutingContext.ActionParameters и строю массив типов параметров, переданных в запросе. Затем я могу использовать перегрузку Type.GetMethod (string, type ()), чтобы уточнить свой запрос.
К моменту вызова OnActionExecuting
метод действия еще не был выполнен, поэтому вы никак не можете знать, вернет ли этот метод действия какой подкласс ActionResult
. Так что, если только вы не можете прибегнуть к реализации CIL-анализа (что, как мне кажется, может очень быстро стать уродливым), я не думаю, что то, что вы хотите сделать, возможно.
Тем не менее, разве того факта, что вы перенаправляете пользователей на представление, когда контроллер недоступен, не достаточно? Я имею в виду, я не понимаю, почему вы хотите перенаправлять пользователей на результат JSON или частичное представление.