1

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 )
Community
  • 1
  • 1
BH4EHN
  • 169
  • 1
  • 10
  • I suggest having a play around with the route configs. If it isn't doable directly via routeing, then you could just make it route to a 'handler' action that evaluates the `action` param and redirects to the specified action. Which should be simple enough – musefan Sep 23 '16 at 09:35
  • Generally routes in the route config can't be configured with query strings. If you try to do that it will throw an error. I'm not sure if there is a way to overthrow the main conventions of the routing. Is there a reason that you'd want to do this, it makes the conventions of MVC redundant. – Luke Sep 23 '16 at 09:37
  • 2
    You don't need to configure query strings in the route config, MVC also checks on the query string and map it to your action parameters assuming you have the matching parameter name with the querystring name – Bon Macalindong Sep 23 '16 at 09:48

1 Answers1

0

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>
BH4EHN
  • 169
  • 1
  • 10