Why does Html.BeginForm generate empty action?
-
28-10-2019 - |
Question
I have a controller in an area called Admin
public class SiteVisitController : Controller
{
public ViewResult ReadyForCompletion() { ... }
public ViewResult CompleteAndExport() { ... }
}
and a view (ReadyForCompletion.cshtml
) that has posts back to a different controller action on the same class
@using (Html.BeginForm( "CompleteAndExport", "SiteVisit" ))
{
<input type="submit" value="Complete & Export" />
}
The generated HTML for this form has a blank action:
<form action="" method="post"> <input type="submit" value="Complete & Export" />
</form>
I want to know why this has a blank action? For more info, I also added in a
@Url.RouteUrl(new { controller = "ReadyForCompletion", action = "SiteVisit", area = "Admin" })
which also printed out an empty string. Also, if I use an empty Html.BeginForm()
it generates the correct action.
Registered routes are
context.MapRoute(
"Admin_manyParams",
"Admin/{controller}/{action}/{id}/{actionId}",
new { action = "Index", id = UrlParameter.Optional, actionId = UrlParameter.Optional }
);
Solution
I believe your problem is caused by having consecutive optional parameters. I was not able to replicate your problem until I changed the route to contain two optional parameters.
OTHER TIPS
For those of you encountering this issue using ASP.NET Core the root cause is the same, though the solution is slightly different. I first saw this in Core using multiple default values when calling .MapRoutes()
. E.g.
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Foo", action = "Bar" }
);
The workaround is to place the default values into the string template:
routes.MapRoute(
name: "default",
template: "{controller=Foo}/{action=Bar}/{id?}"
);
YMMV.