我能得到一个动作的返回类型从操作过滤器? [英] Can I get an Action's return type from an Action Filter?

查看:465
本文介绍了我能得到一个动作的返回类型从操作过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我创建一个自定义操作过滤器的ASP.NET MVC 2应用程序。此滤波器坐在应用程序中的控制器,并从数据库验证函数当前是否可用。

I have an ASP.NET MVC 2 application in which I am creating a custom action filter. This filter sits on the controllers in the application and verifies from the database whether that function is currently available.

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动作的操作。

My problem is that depending on the action that has been requested I need to redirect the user to an action that returns either a view, partial views or JSON.

由于ActionExecutingContext我可以找出的最初的返回类型请求的操作是什么?

Given the ActionExecutingContext can I find out what the return type of the originally requested action is?

编辑:

好吧,我越来越近,但有一个问题。

Ok, I'm getting closer but have another problem.

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

我可以使用反射来查找操作方法的返回类型。我的问题是,如果我有一个控制器上的以下方法:

I can use reflection to find the return type of the action method. My problem is if I have the following methods on a controller:

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抛出。

I get an AmbiguousMatchException thrown.

使用我在OnActionExecuting方法的信息,反正是有被更多的precise以确定被调用过载?

With the information I have in the OnActionExecuting method, is there anyway of being more precise with determining the overload that is being called?

推荐答案

好吧,这是解决我想出了。

Ok, this is the solution I have come up with.

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(字符串)调用失败识别方法的要求,我取从ActionExecutingContext.ActionParameters集合的参数集合,打造类型的请求传递的参数数组。那么我可以用Type.GetMethod(字符串,类型()),超载更加具体谈谈我的要求。

If the Type.GetMethod(string) call fails to identify the method requested, I fetch the parameters collection from the ActionExecutingContext.ActionParameters collection and build an array of the types of the parameters passed in the request. I can then use the Type.GetMethod(string,type()) overload to be more specific about my request.

这篇关于我能得到一个动作的返回类型从操作过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆