0

I have created a sample ASP.NET MVC website in VS 2015 and in a view i am using the extension Ajax.BeginForm to post login credentials to controller, and on OnSuccess callback i want to check for server errors and if any show the error to user else - redirect to home page, here is the code (It returns always error intentionally to test the callback):

Model

[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }

View

<script>
    function onLogInSuccess(result) {
        /*
          Instead of getting here after returning the result from 
          Controller all the view(in the browser) is replaced with:
          {"status":"ERROR","message":"Invalid Email or Password.","returnUrl":"/"}
        */
        if (result.status === "OK") {
            window.location.href = result.returnUrl;
        } else {
            alert(result.message);
        }
    }

    $("#buttonLogIn").on('click', function (e) {
        $("#formLogIn").submit();
    });
</script>
<section id="loginForm">
@using (Ajax.BeginForm("LogIn", "Custom", null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "onLogInSuccess" }, new { @class = "form-horizontal", role = "form", id = "formLogIn" }))
{
    @Html.AntiForgeryToken()
    <h4>Login:</h4>
    <hr />
    <div class="form-group">
        <label id="loginValidation" class="col-md-12 validation-label"></label>
    </div>
    <div class="form-group">
        <label class="col-md-12 control-label" for="LogInUsername">Username</label>
        <div class="col-md-12">
            <input class="form-control" id="LogInUsername" name="Username" type="text" value="" />
        </div>
    </div>
    <div class="form-group">
        <label class="col-md-12 control-label" for="LogInPassword">Password</label>
        <div class="col-md-12">
            <input class="form-control" id="LogInUsername" name="Password" type="password" value="" />
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-4 col-md-12">
            <input type="button" id="buttonLogIn" value="Log in" class="btn btn-default" />
        </div>
    </div>
}
</section>

Controller

[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult LogIn(LoginModel Credentials)
{
    string returnUrl = "/";
    string status = AsyncRequestStatus.ResultError; //"ERROR"
    string message = "Invalid Email or Password.";

    return Json(new { status = status, message = message, returnUrl = returnUrl });
}
M.Veli
  • 519
  • 1
  • 6
  • 15
  • 2
    Because you have not included `jquery.unobtrusive-ajax.js` so its doing a normal submit (not an ajax submit). But using ajax when you wnat to redirect is pointless and probably degrading your app. Use a normal submit, check `ModelState.IsValid` and redirect if so, or return the view if not. And use the the HtmlHelper methods to generate your view including the `ValidationessageFor()` and `ValidationSummary()` methods to display the error messages. –  Jan 27 '16 at 03:43
  • **jquery.unobtrusive-ajax.js** was the reason, yes. (I am not using HtmlHelper methods, because I want to show only one error message not all of them. Something like ValidationSummary with only the first error and changing the border color of all fields that is not valid, so it is kind of custom validation.) If you post this comment as an answer I will accept it. – M.Veli Jan 28 '16 at 17:25

2 Answers2

1

If your displaying only the json returned by your LogIn() method, then its because you have not included jquery.unobtrusive-ajax.js file in your view. As a result, Ajax.BeginForm() falls back to making a normal submit

0

If you're sending some status code different than 200 from server side, the error callback is executed:

$.ajax({
    url: '/foo',
    success: function(result) {

    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('you will see this');
    }
});

check this link out https://stackoverflow.com/a/4707762/3521012

Community
  • 1
  • 1
RogerEdward
  • 121
  • 1
  • 7
  • No, I am not sending status code, the **status** in controller is a local variable of type string (updated the controller code), also I tried with OnFailure callback which does not fired either.. The whole content of the screen just replaces with: { status = "ERROR", message = "Invalid Email or Password.", returnUrl = "/" }, it shows directly the JSON provided by the Controller. – M.Veli Jan 24 '16 at 20:10