1

I don't know how the AjaxForm's will know when fire OnSuccess or OnError method. But, is is possible to make them fire OnSuccess or OnError method based on Boolean value?

@using(Ajax.BeginForm("AddAttendeeManual", "Attendee", new AjaxOptions { HttpMethod = "POST", OnSuccess = "doneManualEmail" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()
    @Html.HiddenFor(m=>m.SelectedManualEmail.AppointmentId)


    <div class="form-group">
    @Html.LabelFor(m => m.SelectedManualEmail.Email, new { @class = "col-md-2 control-label" })
    <div class="col-md-8 input-group">
        @Html.TextBoxFor(m => m.SelectedManualEmail.Email, new {@class = "form-control",PlaceHolder="Email"}) 
        <input type="submit" id="btnManual"class="btn btn-default" value="Add>>" />
     </div>
     </div>
} 

and this is the OnSucess method(on the same view)

   function doneManualEmail() {
        alert("Success");
        $(@Html.IdFor(m=>m.SelectedManualEmail.Email)).val('');
        var url = $("#invitedPeoples").data('url');
        $.get(url, function (data) {
            $('#invitedPeoples').html(data);
        });
    };   

and this is the controller method

[HttpPost]
[ValidateAntiForgeryToken]
public void AddAttendeeManual(CreateAppointmentSelectPersons manualEmail)
{      
     _attendeeRepository.AddManualAttendee(manualEmail.SelectedManualEmail.AppointmentId,
     manualEmail.SelectedManualEmail.Email);                             
}

currently when the form is submitted it calls controller's method (where person is added to database) does and after that call's the OnSuccess method mentioned above. No problem till now.

But now, I want to check something (if person exists) in controller, this is my controller's method now

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddAttendeeManual(CreateAppointmentSelectPersons manualEmail)
{
   bool result =  _attendeeRepository.CheckIfAttendeeExists(manualEmail.SelectedManualEmail.AppointmentId, manualEmail.SelectedManualEmail.Email);
    if(!result)
    {
        _attendeeRepository.AddManualAttendee(manualEmail.SelectedManualEmail.AppointmentId,
        manualEmail.SelectedManualEmail.Email);
        //call OnSuccess method


    }
    else
    {               
        //add ModelStateError on client side?? or make it fire OnError method?
    }

}

PS: There is not get method for this view. Based upon bool value I want the form to fire OnSuccess or OnError method, and if it is OnError then add a error(like a modelstate) on the clientside.

Would that be possible?

Cybercop
  • 8,475
  • 21
  • 75
  • 135

2 Answers2

4

Ajax.BeginForm OnError method basically is jQuery.ajax error function and gets called when the request fails. So in your case it cannot be fired unless you manually throw an exception. In my opinion, this is a solution, but not a good one. CheckIfAttendeeExists is normal business case and should be handled by the code, not by throwing an exception.

Instead you can return a JSON that indicates whether attendee exists or not:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddAttendeeManual(CreateAppointmentSelectPersons manualEmail)
{
   bool result = _attendeeRepository.CheckIfAttendeeExists(manualEmail.SelectedManualEmail.AppointmentId, manualEmail.SelectedManualEmail.Email);
    if(!result)
    {
        _attendeeRepository.AddManualAttendee(manualEmail.SelectedManualEmail.AppointmentId,
        manualEmail.SelectedManualEmail.Email);
    }
    return Json(new { AttendeeExists = result, ErrorMessage = "Attendee already exists" });
}

On the client check for the property:

function doneManualEmail(response) {
    if(response.AttendeeExists) {
         alert(response.ErrorMessage); // or something else
    }
    else {
        alert("Success");
        $(@Html.IdFor(m=>m.SelectedManualEmail.Email)).val('');
        var url = $("#invitedPeoples").data('url');
        $.get(url, function (data) {
            $('#invitedPeoples').html(data);
        });
    }
};

The ModelState won't help you here, because your model is valid. You can return an error message with JSON. See the edited code.

Zabavsky
  • 13,340
  • 8
  • 54
  • 79
  • awesome, but would it be possible to add error (like a modelstate) on the client side? inside `if(response.AttendeeExists){...}`? – Cybercop Feb 20 '14 at 09:26
  • Or should I ask seperate question for that? – Cybercop Feb 20 '14 at 09:34
  • but it would show a alert, I meant show the error that you get as one of the `ModelStateError`, just above the form. i know modelstate is valid and can't be used but show error. But i mean show error not as alert but just above form as text. But then from front end – Cybercop Feb 20 '14 at 09:43
  • @Biplov13, if you want to take advantage of the `DataAnnotations` and `@Html.ValidationSummary()`, you need to write a custom validator and return a `PartialView` with validation errors. – Zabavsky Feb 20 '14 at 09:49
  • How about this? http://stackoverflow.com/questions/2808327/how-to-read-modelstate-errors-when-returned-by-json – Cybercop Feb 20 '14 at 10:10
  • @Biplov13, you can try of course, but I prefer to not mess manually with validation messages using javascript, as they are generated on a server. Better return already prepared partial view. – Zabavsky Feb 20 '14 at 10:17
  • so the error message would be in partial view? or may be just a div with message? – Cybercop Feb 20 '14 at 10:19
  • @Biplov13, better put all inside a form in a partial view and update it. – Zabavsky Feb 20 '14 at 10:21
1
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddAttendeeManual(CreateAppointmentSelectPersons manualEmail)
{
    bool result = _attendeeRepository.CheckIfAttendeeExists(manualEmail.SelectedManualEmail.AppointmentId, manualEmail.SelectedManualEmail.Email);
    if(!result)
    {
        _attendeeRepository.AddManualAttendee(manualEmail.SelectedManualEmail.AppointmentId,
        manualEmail.SelectedManualEmail.Email);
        //this doesn't necessarily guarantee the onError won't get called
        //there are other reasons your ajax request could fail
    }
    else
    {               
        //throw an exception
        throw new Exception("Ajax Call Failed!");
    }

}

Also see: ASP.NET MVC Intentional Ajax Failure

Community
  • 1
  • 1
Jakotheshadows
  • 1,485
  • 2
  • 13
  • 24
  • but throwing an exception, wouldn't it crash the application? – Cybercop Feb 20 '14 at 09:16
  • @Biplov13 No it won't. It will just cause that ajax request to fail. While debugging, I run into exceptions all the time that are caused by bad front end code. You typically fix the front end code and reload the page without rebuilding or restarting IIS Express and it all seems to keep working just fine. – Jakotheshadows Feb 20 '14 at 09:19
  • but i think the approach of @Zabavsky is better what do you think? – Cybercop Feb 20 '14 at 09:22
  • Definitely. You don't want to add to the confusion that is a failed ajax call by having to eliminate the possibility that an exception you threw caused it to fail. – Jakotheshadows Feb 20 '14 at 09:32