Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asp.net mvc Type.GetMethod when two action with same name, but get and post

in asp.net mvc 4, I write a custom Exception handler, working as a Attribute named HandleCustomError.

In this handler, I should know which action the current request for, then I can know what kind of return type for this action. I will return different data for "return type view() and json".

But, now I have two action with the same name, but one is for "Get", other is for "Post".The method "GetMethod" return an error: " System.Reflection.AmbiguousMatchException "

public class HandleCustomError : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(System.Web.Mvc.ExceptionContext filterContext)
    {
        //base.OnException(filterContext);
        if (filterContext.ExceptionHandled)
        {
            return;
        }
        else
        {
            //Determine the return type of the action
            string actionName = filterContext.RouteData.Values["action"].ToString();
            Type controllerType = filterContext.Controller.GetType();
            var method = controllerType.GetMethod(actionName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
            var returnType = method.ReturnType;
        }
        ....(Omitted)
like image 252
Guan Wan Avatar asked Sep 15 '14 03:09

Guan Wan


1 Answers

I also came across this issue that below line was giving Ambigeous issue

controllerType.GetMethod(actionName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

Reason was that controller has two method with same name one is

[HTTPGET]

and other iis

[HTTPPOST]

.

For to get exact method I use GetMethods and LINQ. Note: In controller writting [HTTPGet]**on action is not compulsory for get method i.e. on action if HTTpGet is not written the by default .net will consider it as **[HttpGet]. But for post action it is compulsory. Will use this property for finding the correct method.

Steps 1. Find Type of request 2. Find the action using reflection

  1. Finding Request type:

var actionName = filterContext.RouteData.Values["action"].ToString(); Type typeOfRequest = filterContext.HttpContext.Request.RequestType.ToLower() =="get"?typeof(HttpGetAttribute):typeof(HttpPostAttribute);

  1. Finding method:
var cntMethods = controllerType.GetMethods()
                 .Where(m => 
                    m.Name == actionName &&
                    (  (  typeOfRequest == typeof(HttpPostAttribute) && 
                          m.CustomAttributes.Where(a => a.AttributeType == typeOfRequest).Count()>0
                       )
                       ||
                       (  typeOfRequest == typeof(HttpGetAttribute) &&
                          m.CustomAttributes.Where(a => a.AttributeType == typeof(HttpPostAttribute)).Count() == 0
                       )
                    )
                );
            MethodInfo actionMethodInfo = actionMethodInfo = cntMethods != null && cntMethods.Count() == 1 ? cntMethods.ElementAt(0):null;

Reference : https://techatfingers.wordpress.com/2016/06/14/session-state-on-action/

like image 51
SeeTheC Avatar answered Nov 08 '22 21:11

SeeTheC