Solved

MVC Ajax.BeginForm how to handle OnSuccess and OnFailure from Controller?

Posted on 2014-12-17
8
9,733 Views
Last Modified: 2014-12-18
Hello all,

I am trying to do something a different way with Ajax posting.   I have a MVC Razor form with an Ajax.BeginForm on it and submit button.   When I click submit I get into my Save action in the Controller.   I can't find a good example on how to handle the Controller action.   I have an OnSuccess and OnFailure in the BeginForm such as this:

@using (Ajax.BeginForm("SaveContact", "Contact", new AjaxOptions { HttpMethod = "Post", OnSuccess = "alert('success');", OnFailure = "alert('failure');" }))

What I actually want to do is call a JavaScript function on the OnSuccess or OnFailure and if Failure I want to somehow pass the error message from the Catch statement in the controller so I can display that in a div tag on the view.  So if it hits the catch (Exception e) I want to pass the e.Message back to the view to display in a div tag.   The problem is I don't know how to handle the controller method on Save if its a ActionMethod or a JsonResult etc.

Can anyone provide a quick example on how to handle the controller method and to get that back to the view?   I cant even find a good example on how to pass back so the OnSuccess or OnFailure gets called after my Save in the controller.

Thanks All.
0
Comment
Question by:sbornstein2
  • 4
  • 4
8 Comments
 
LVL 52

Expert Comment

by:Carl Tawn
Comment Utility
Basically if you send anything back with a StatusCode of anything other than 200 it will trigger the OnFailure procedure.

Example:
// view
@using (Ajax.BeginForm(new AjaxOptions { OnSuccess = "OnSuccess", OnFailure = "OnFailure" })) {
    <input type="text" id="name" name="name" />
    <input type="submit" />
}

<script language="javascript" type="text/javascript">
    function OnSuccess(data) {
        alert(data);
    }

    function OnFailure(xhr, status) {
        alert('Error: '+xhr.statusText);
    }
</script>

Open in new window

Sample controller action to trigger OnFailure:
[HttpPost]
public ActionResult Index(string name)
{
    return new HttpStatusCodeResult(404, "Can't find that");
}

Open in new window

0
 

Author Comment

by:sbornstein2
Comment Utility
Hi Carl so what would I pass back in the controller after I make the save for example?  Is the status code the common thing to pass back at the view?   I had a way using the RazorViewEngine that essentially passed back a partial view as a string and it then refreshed the view itself all ajax.  Works real nice but its confusing to some so I want to dumb it down make it cleaner.
0
 

Author Comment

by:sbornstein2
Comment Utility
Carl I was just thinking that on the save if success I actually need to pass back the viewmodel to the view based on if they click save again the identity column a HiddenFor I need populated if they click the save button again it should act as an update.
0
 
LVL 52

Expert Comment

by:Carl Tawn
Comment Utility
In that case it might be just as easy to use a full postback rather an Ajax postback.  If you want to use Ajax, then i'd suggest wrapping your editor as a partial view; that way you can save your model, and then return a PartialView with the  updated model and switch it out in your page.

I can put together a basic example if you need it.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:sbornstein2
Comment Utility
That would be great.  What I am thinking not sure it makes sense.  I will have a div tag at the top of my view that will act as a status bar and show an error message.   In the scenario I have a view that has a grid on it and the 1st col has a detail link that takes the user to a data entry form for save.   On success I actually prob want to redirect them back to the grid master.   I could use a Ajax.BeginForm on failure I pass back the response status and keep them on the data entry page.   On success save I pass back to the success a Json Url that on the client I perform a window.location to the Url back to the grid master.   That seem feasible or senseless based on the redirect anyway?  I am just thinking on failure to stay on the page and show the error from the server.
0
 
LVL 52

Expert Comment

by:Carl Tawn
Comment Utility
You could simply perform a RedirectToAction() if the save is successful (essentially sending the user back to a different page) or return an error to the current view otherwise.

Like:
[HttpPost]
public ActionResult Save(Person model)
{
    try
    {
           repository.Save(model);      // do something to save the model

           // save successful so redirect
           return RedirectToAction("Index");
    }
    catch (Exception ex)
    {
         // save failed so return error to view
         return new HttpStatusCodeResult(404, "Broken");
    }
}

Open in new window

0
 
LVL 52

Accepted Solution

by:
Carl Tawn earned 500 total points
Comment Utility
Anyway, while you're thinking about which way to go, here's a simple example of how you would do in-line create/edit using a partial view.

First, a simple model:
public class Person
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Open in new window

Then the controller:
public class HomeController : Controller
{
    //
    // GET: /Home/

    public ActionResult Index()
    {
        // create a new, empty, model (ID of -1 indicates it is new)
        Person model = new Person { ID = -1 };
        return View(model);
    }

    [HttpPost]
    public ActionResult Save(Person model)
    {
        // pretend we have saved it somewhere by giving it a non-negative ID
        model.ID = 1;

        ModelState.Clear();

        // re-render the partial view and return
        return PartialView("PersonPartialView", model);
    }
}

Open in new window

Next the PartialView (named PersonPartialView in this case):
@model MvcApplication1.Models.Person

@Html.HiddenFor(model => model.ID)     
<span>@Model.ID</span>      <!-- extra label purely to make it easier to see the ID for demo purposes -->
<div>
    <span>First name: </span>
    @Html.TextBoxFor(model => model.FirstName)
</div>
<div>
    <span>Last name: </span>
    @Html.TextBoxFor(model => model.LastName)
</div>

Open in new window

And finally the main View:
@model MvcApplication1.Models.Person

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@using (Ajax.BeginForm("Save", new AjaxOptions { HttpMethod = "POST", OnSuccess = "OnSuccess", OnFailure = "OnFailure" }))
{
    <div id="container">
        @{ Html.RenderPartial("PersonPartialView", Model); }
    </div>
    <input type="submit" />
}

<script language="javascript" type="text/javascript">
    function OnSuccess(data) {
        $("#container").html(data);
    }

    function OnFailure(xhr, status) {
        alert('Error: '+xhr.statusText);
    }
</script>

Open in new window

So basically this lets us create a new "Person", fill in the details and submit it.  We switch out the updated model so it reflects the update to the ID.  Then, if we click Save again we post back the current ID so we can update the record.
0
 

Author Closing Comment

by:sbornstein2
Comment Utility
awesome info thanks so much Carl
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Requirements JQuery 1.6+ HTML CSS Introduction This article was inspired by an EE question (http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_28372511.html) on how to make a page show some balloons animate up a page…
Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now