CloverYang CloverYang - 2 months ago 13
ASP.NET (C#) Question

Is there any way to set ActionName in QueryString in ASP.NET MVC 5?

We all know url in ASP.NET MVC always like

example.com/controller/action?param1=value1&param2=value2


I'd like to know is there a way to put action name in query string just like
example.com/controller?aciton=index&param1=value1&param2=value2
(notice action=index in query string), and make ASP.NET MVC route the url to the corresponding controller and action. The name of the query name can be
action
or something else.

--- update 28th Sep ---

The actual situation is I have a form, inside the form is a table with radio button each column and some button (create, edit, delete etc.) above the table. These buttons go to different action in same controller.

As a result of search, I've got some solutions:


  1. handle onsubmit via JavaScript and change the action property of form. Answer link

  2. write a "route" method in controller to re-route the request. Answer link ( I think this is not a graceful solution )

  3. write a custom attribute let ASP.NET MVC route to corresponding action base on query. This anwser and this answer ( Very close to my original idea, I am currently using this solution )


Answer

I'm the questioner and just several hours after I update the question, I finally figure out the solution. That is write a custom Route.

public class QueryActionRoute : Route
{
    public QueryActionRoute(string url, object defaults) : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler()) { }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);
        var action = httpContext.Request["action"];
        if (routeData != null)
        {
            if (!string.IsNullOrEmpty(action))
            {
                routeData.Values["action"] = action;
            }
        }
        else
        {
            routeData = new RouteData()
            {
                Values = { {"action", "Index"} }
            };
        }
        return routeData;
    }
}

and replace the default route

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.Add(
            "Default",
            new QueryActionRoute(
                "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional }));
    }
}

after that you can access an action via
example.com/home/about?param=value(you can emit action name if the action is "index") like before
or
example.com/home?action=about&param=value.

I's really helpful when you need to specify different buttons to go different actions in form. You can make it in this way:

<form action="@Url.Action("Index")">
    <button name="action" value="Create">Create</button>
    <button name="action" value="Details">Detail</button>
    <button name="action" value="Edit">Edit</button>
    <button name="action" value="Delete">Delete</button>
</form>