Я могу получить тип возврата Действия от Фильтра Действия?

У меня есть приложение 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, имеет ли так или иначе то, чтобы быть более точным с определением перегрузки, которую называют?

11
задан Nick 19 May 2010 в 15:05
поделиться

2 ответа

Хорошо, это решение, которое я придумал.

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 ()), чтобы уточнить свой запрос.

2
ответ дан 3 December 2019 в 09:40
поделиться

К моменту вызова OnActionExecuting метод действия еще не был выполнен, поэтому вы никак не можете знать, вернет ли этот метод действия какой подкласс ActionResult. Так что, если только вы не можете прибегнуть к реализации CIL-анализа (что, как мне кажется, может очень быстро стать уродливым), я не думаю, что то, что вы хотите сделать, возможно.

Тем не менее, разве того факта, что вы перенаправляете пользователей на представление, когда контроллер недоступен, не достаточно? Я имею в виду, я не понимаю, почему вы хотите перенаправлять пользователей на результат JSON или частичное представление.

0
ответ дан 3 December 2019 в 09:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: