Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different MVC4 action based on GET variable

Is there a way to get MVC4 to call different actions based on a GET variable in the URL?

For example, let's say I have the following two actions.

[HttpPost]
public ActionResult SubmitCrash(CrashReport rawData)
{
  return View();
}


[HttpPost]
public ActionResult SubmitBug(BugReport data)
{
  return View();
}

Is there a way I can use the following URLs to have MVC4 'choose' which action to call?

http://MySite/Submit?Crash (calls 'SubmitCrash')  
http://MySite/Submit?Bug (calls 'SubmitBug')

UPDATE:
I am very much aware that I can use actions / urls the way they are, and do stuff with routing to make it happen (which is what I am doing now), but I am really interested in the GET vars part of the question.

like image 564
A.R. Avatar asked Mar 20 '13 15:03

A.R.


1 Answers

It's not as neat as it could be, but you may use 'root' action for this:

public ActionResult Submit(string method)
{
  return Redirect("Submit"+method);
}

public ActionResult SubmitCrash()
{
  return View();
}

public ActionResult SubmitBug()
{
  return View();
}

Edit
I have extend ActionNameAttribute to meet your needs, so you may write this:

//handles http://MySite/Submit?method=Crash
[ActionNameWithParameter(Name = "Submit", ParameterName = "method", ParameterValue = "Crash")]
public ActionResult SubmitCrash()
{
  return View();
}

//handles http://MySite/Submit?method=Bug
[ActionNameWithParameter(Name = "Submit", ParameterName = "method", ParameterValue = "Bug")]
public ActionResult SubmitBug()
{
  return View();
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class ActionNameWithParameterAttribute : ActionNameSelectorAttribute
{
    public string Name
    {
        get;
        private set;
    }
    public string ParameterName
    {
        get;
        private set;
    }
    public string ParameterValue
    {
        get;
        private set;
    }
    public ActionNameAttribute(string name, string parameterName, string parameterValue)
    {
        if (string.IsNullOrEmpty(name))
        {
            throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
        }
        this.Name = name;
        this.ParameterName = parameterName;
        this.ParameterValue = parameterValue;
    }
    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        return string.Equals(actionName, this.Name, StringComparison.OrdinalIgnoreCase)
            && string.Equals(controllerContext.HttpContext.Request.QueryString.Get(ParameterName)
                , this.ParameterValue
                , StringComparison.OrdinalIgnoreCase);
    }
}
like image 132
Dima Avatar answered Oct 26 '22 09:10

Dima