0

I have a small project very basic, VS 2013, .Net Framework 4.5 with System.Web.Mvc (5.2.7) installed.

No special routes or authentication; just 3 controllers scaffolded from an EF context. One of the controllers is called DataRoutesController, and another is DataRouteViewFieldsController. DataRouteViewFields is a child (foreign key) of DataRoute. On the Edit page for DataRoute I have a table which lists the related ViewFields, each row with it's own edit and delete buttons.

<button class="btn btn-sm btn-primary" 
  onclick="location.href='@Url.Action("Edit", "DataRouteViewFields", new { id = item.RouteId, name = item.Name })'" 
  title="Edit">
  <span class="glyphicon glyphicon-pencil"/>
</button>

When I click the button it calls the correct controller and proceeds to the return statement.

public ActionResult Edit(int? id, string name)
{
    DataRouteViewField dataRouteViewField = db.DataRouteViewFields.Find(id, name);
    return View(dataRouteViewField);
}

But then, for some reason I can't comprehend I calls the DataRouteController Index() route and returns the wrong page.

public ActionResult Index()
{
    var dataRoutes = db.DataRoutes.Include(d => d.Connection);
    return View(dataRoutes.ToList());
}

This behavior is not observed when I don't use the button. If I type the URL to edit the ViewField manually, it works as expected.

When I step though the code (F11) following the return from DataRouteViewFieldController.Edit(...), it proceeds to _ViewStart, then to the Edit.cshtml for DataRouteViewFieldController like it should. When it finishes Edit.cshtml it renders the wrong page. The Edit.cshtml page is largely blank for troubleshooting purposes:

@model ctNetData.DataRouteViewField
@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Edit</h2>

If I add a break to DataRoutesController.Index() then the process starts flipping back and forth between lines of code in DataRouteViewFieldsController.Edit(...) and DataRoutesController.Index() with F11, like it's processing two threads at the same time.

Anyone recognize what's going on here?

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}
Geoff B
  • 33
  • 7
  • Does that Find actually return a single concrete instance? If not, make sure you call .First or something. It might think it could have a list and be confused. That's all I can think of...oh, and for grins, change that location.href button to just a normal anchor link. See if that matters. – Nikki9696 Apr 14 '21 at 23:44
  • Using an Html.ActionLink instead of Url.Action performs as expected. But that only deepens the mystery for me. I have the same Url.Action in other projects and they all behave. `@Html.ActionLink("Edit", "Edit", "DataRouteViewFields", new { id = item.RouteId, name = item.Name }, null)` – Geoff B Apr 15 '21 at 14:13

1 Answers1

0

The problem was that my button, despite not being of type "submit" or "input" was inducing the page's form to submit. Moving the button(s) outside the form corrected the behavior.

According to this page, How to prevent buttons from submitting forms <Button/> has a default type of "submit". So there are two remedies. Move the foreign key table outside of the form, or specify the button's type as button.

@using (Html.BeginForm())
{
 //Button submits form, has behavior described above
 <button class="btn btn-xs btn-primary" onclick="location.href='@Url.Action("Edit", "DataRouteViewFields", new { id = item.RouteId, name = item.Name })'" title="Edit">
    <span class="glyphicon glyphicon-pencil" />
 </button>
 //Button below works as expected
 <button type="button" class="btn btn-xs btn-primary" onclick="location.href='@Url.Action("Edit", "DataRouteViewFields", new { id = item.RouteId, name = item.Name })'" title="Edit">
    <span class="glyphicon glyphicon-pencil" />
 </button>
}
//Button works as expected
<button class="btn btn-xs btn-primary" onclick="location.href='@Url.Action("Edit", "DataRouteViewFields", new { id = item.RouteId, name = item.Name })'" title="Edit">
    <span class="glyphicon glyphicon-pencil" />
</button>
Geoff B
  • 33
  • 7