2

I am trying to solve a small hiccup with my MVC application. Everything is pretty much the usual setup with CRUD urls served by Controllers.

In one of the views I had to implement a validation check for data entered that will not save the data. It sounds complicated but basically it's just the idea of submitting a form to two different URLs: one will save the data (whatever it is) and redirect to Index, the other will perform validation and show any errors.

The problem I am having is that the "Check" action does not retain the value in the URL. To show some code and examples, let's say I go to http://localhost/MyApp/Items/Edit/3, and I click on the "Check" button, I will be presented the same view, with errors highlighted, but the URL will change to http://localhost/MyApp/Items/Check.

Is there a way to retain the former URL?

The way I am deciding which post action to hit is through some small javascript that changes the form action attribute before submitting:

$(document).ready(function() {
    $(".submit").click(function (ev) {
        var $buttonClicked = $(this);

        var $form = $("form");

        $form.attr("action", $buttonClicked.data("action")); // we store the URL in the data-action attribute of the button
        $form.submit();
    });
});

The controller actions are simple:

  [HttpPost]
  public ActionResult Edit(MyItem model) {
      if (UserCanEdit(model)) { // no validation, only auth checks
          _service.Update(model);
          return RedirectToAction("Index");
      }
      else {
          // access denied
          return RedirectToAction("Index");
      }
  }

  [HttpPost]
  public ActionResult Check(MyItem model)
  {
      var validation = _service.Validate(model);

      if (validation != ValidationResult.Success) {
          foreach (var memberName in validation.MemberNames) {
              ModelState.AddModelError(memberName, validation.ErrorMessage);
          }
      }
      return View("Edit", model); // we use the same view, show errors as validation errors
  }

Any idea?

Tallmaris
  • 7,605
  • 3
  • 28
  • 58

1 Answers1

2

One approach is to route both to the same action and add extra parameter for mode so your action look like:

[HttpPost]
public ActionResult Edit(MyItem model, bool checkOnly) 
{
   return checkOnly ? Check(model) : Edit(model);
}

private ActionResult Edit(MyItem model)  {...}
private ActionResult Check(MyItem model)  {...}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • I tried that as well, using the `submitButton` value as a string (either Check or Edit), but the returning url was something like `http://localhost/MyApp/Items/Edit/Edit`... I'll keep exploring this option. – Tallmaris Sep 04 '15 at 07:31
  • That is the correct answer, and indeed I found another reference here too: http://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mvc-framework. I had problems with my actual form action URL which was a bit gobbled up. Thanks! – Tallmaris Sep 04 '15 at 09:37