I have a table of records being displayed in a partial view and some of them have no ID values. So I am trying to use an alternative field as an ID when clicking the Edit link for a particular record. I’m not sure if I can legally have two Post action methods, even though I am using different methods names and params.
Currently, if I click on a record with an ID the correct action method gets called. If I select a record with no ID (instead using an “account” string ID which is unique), I get a 404.
RouteConfig:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Partial View:
...
<td>
@if (item.ID != null)
{
@Html.ActionLink("Edit", "EditBudget", new { id = item.ID })
}
else if (item.Account != null)
{
@Html.ActionLink("Edit", "EditAccountBudget", new { account = item.Account })
}
</td>
BudgetsController:
// POST: Budgets/Edit/5
[Route("edit/{id?}")]
[HttpPost]
public ActionResult EditBudget(int? id = null, FormCollection collection = null)
{
...
// Responding correctly for URL: http://localhost:4007/edit/19
}
[Route("editaccountbudget/{account}")]
[HttpPost]
public ActionResult EditAccountBudget(string account)
{
...
// Getting 404 for URL: http://localhost:4007/editaccountbudget/6000..130
}
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
ActionLink renders a regular anchor (<a />) tag, so it only does GET not POST. If you want to POST values, you need to use an actual form (either building your own tag, or using Html.BeginForm() ) and then include inside that form’s scope a submit button.
Method 2
Assuming that EditBudget is your controller name , you can change
your route to this to avoid confusing ( or leave as it is since the attribute route will be ignored) and remove [POST] from your action too:
[Route("~EditBudget/EditAccountBudget/{account}")]
Also change:
@Html.ActionLink("Edit", "EditAccountBudget", new new { account = item.Account })
To:
@Html.ActionLink("EditAccountBudget", "EditBudget", new { account = item.Account })
If you use razor pages template controls you need to have both controller and action parts of the route according your route mapping. If you use ajax or httpclient you can have any syntax of route.
Method 3
Your BudgetsController should look like below without HttpPost Attribute and without Route Attribute as you are using method names in ActionLink. You can use HttpGet attribute if you wish.
Also no need of FormCollection collection parameter in EditBudget method. You will not get anything as its Get not Post.
public ActionResult EditBudget(int? id = null)
{
}
public ActionResult EditAccountBudget(string account)
{
}
Method 4
As some have pointed out, this is a GET request. If the ID was null, I had to pass the model because I needed more than the account ID to construct the database query.
Partial View:
@if (item.ID != null)
{
@Html.ActionLink("Edit", "EditBudget", new { id = item.ID })
}
else if (item.Account != null)
{
@Html.ActionLink("Edit", "EditBudget", new { account = item.Account,
SelectedDepartment = item.SelectedDepartment, SelectedYear = item.SelectedYear })
}
BudgetsController:
// GET
public ActionResult EditBudget(int? id, BudgetsViewModel model)
{
repo = new BudgetDemoRepository();
if (id != null)
{
// Pass id to repository class
}
else
{
// Pass account and other params to repository class
}
return View(...);
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0