81

I would like to control when to reply an error message and when a success message but I am always get the error message:

here is what I am trying to do:

 $.ajax({
                type: "POST",
                data: formData,
                url: "/Forms/GetJobData",
                dataType: 'json',
                contentType: false,
                processData: false,

                success: function (response) {                    
                   alert("success!") 
                },
                error: function (response) {
                   alert("error") // I'm always get this.
                }

            });

Controller:

         [HttpPost]
            public ActionResult GetJobData(Jobs jobData)
            {

              var mimeType = jobData.File.ContentType;
              var isFileSupported = AllowedMimeTypes(mimeType);

             if (!isFileSupported){        
                     //  Error
                    Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    return Content("The attached file is not supported", MediaTypeNames.Text.Plain);    
             }
            else
              {
                    //  Success
                    Response.StatusCode = (int)HttpStatusCode.OK;
                    return Content("Message sent!", MediaTypeNames.Text.Plain);     

               }   

            }
4
  • Add an if condition... I'm not sure what answer you're expecting here. Commented Oct 28, 2014 at 9:45
  • Your hitting error because the code after the first return statement is not being run. You may want to move the code after the comment for success, before the previous return statement. Commented Oct 28, 2014 at 9:49
  • I fixed the question. now my question is clear. Commented Oct 28, 2014 at 9:50
  • It's been years since this was asked, but the reason you're probably getting an error is the datatype parameter in your Ajax request. You're telling Ajax to expect a JSON, but you're returning plain text: Ajax: "datatype": The type of data that you're expecting back from the server Commented Jan 14, 2019 at 14:05

5 Answers 5

144
 $.ajax({
    type: "POST",
    data: formData,
    url: "/Forms/GetJobData",
    dataType: 'json',
    contentType: false,
    processData: false,               
    success: function (response) {
        if (response.success) {
            alert(response.responseText);
        } else {
            // DoSomethingElse()
            alert(response.responseText);
        }                          
    },
    error: function (response) {
        alert("error!");  // 
    }

});

Controller:

[HttpPost]
public ActionResult GetJobData(Jobs jobData)
{
    var mimeType = jobData.File.ContentType;
    var isFileSupported = IsFileSupported(mimeType);

    if (!isFileSupported){        
         //  Send "false"
        return Json(new { success = false, responseText = "The attached file is not supported." }, JsonRequestBehavior.AllowGet);
    }
    else
    {
        //  Send "Success"
        return Json(new { success = true, responseText= "Your message successfuly sent!"}, JsonRequestBehavior.AllowGet);
    }   
}

---Supplement:---

basically you can send multiple parameters this way:

Controller:

 return Json(new { 
                success = true,
                Name = model.Name,
                Phone = model.Phone,
                Email = model.Email                                
            }, 
            JsonRequestBehavior.AllowGet);

Html:

<script> 
     $.ajax({
                type: "POST",
                url: '@Url.Action("GetData")',
                contentType: 'application/json; charset=utf-8',            
                success: function (response) {

                   if(response.success){ 
                      console.log(response.Name);
                      console.log(response.Phone);
                      console.log(response.Email);
                    }


                },
                error: function (response) {
                    alert("error!"); 
                }
            });
Sign up to request clarification or add additional context in comments.

5 Comments

contentType: 'application/json; charset=utf-8' or false? And why?
me added contentType: 'application/json; charset=utf-8', processData: false and it worked for me.
@ClintEastwood contentType is the type of data you're sending, so it needs to be set to json, a very common one is 'application/json; charset=utf-8'.
It will always hit the success event of ajax call. What I want is to trigger the fail/error handler of the ajax call when something isn't available or is erroneous.
This is a good solution, but doesn't really explain why it's good. According to Ajax spec from JQuery docs: "error": A function to be called if the request fails. In the OP's example, the request hit the server & was processed, it produced a predictable state which couldn't be resolved at that moment; rather than an unexpected error (I.e. Bad HTTP Verb, 404, etc). So by managing this in the success function, you can distinguish normal behaviour from unexpected server errors. I.e. Server request successful, returned with "bad file state" message.
39

Use Json class instead of Content as shown following:

    //  When I want to return an error:
    if (!isFileSupported)
    {
        Response.StatusCode = (int) HttpStatusCode.BadRequest;
        return Json("The attached file is not supported", MediaTypeNames.Text.Plain);
    }
    else
    {
        //  When I want to return sucess:
        Response.StatusCode = (int)HttpStatusCode.OK; 
        return Json("Message sent!", MediaTypeNames.Text.Plain);
    }

Also set contentType:

contentType: 'application/json; charset=utf-8',

4 Comments

contentType: 'application/json; charset=utf-8' or false? And why?
I like this answer for providing example with Response.StatusCode set.
@ClintEastwood contentType is the type of data you're sending, so it needs to be set to json, a very common one is 'application/json; charset=utf-8'.
nice one its should be the proper answer
16

When you return value from server to jQuery's Ajax call you can also use the below code to indicate a server error:

return StatusCode(500, "My error");

Or

return StatusCode((int)HttpStatusCode.InternalServerError, "My error");

Or

Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return Json(new { responseText = "my error" });

Codes other than Http Success codes (e.g. 200[OK]) will trigger the function in front of error: in client side (ajax).

you can have ajax call like:

$.ajax({
        type: "POST",
        url: "/General/ContactRequestPartial",
        data: {
            HashId: id
        },
       success: function (response)  {
            console.log("Custom message : " + response.responseText);
        }, //Is Called when Status Code is 200[OK] or other Http success code
        error: function (jqXHR, textStatus, errorThrown)  {
            console.log("Custom error : " + jqXHR.responseText + " Status: " + textStatus + " Http error:" + errorThrown);
        }, //Is Called when Status Code is 500[InternalServerError] or other Http Error code
        })

Additionally you can handle different HTTP errors from jQuery side like:

$.ajax({
        type: "POST",
        url: "/General/ContactRequestPartial",
        data: {
            HashId: id
        },
        statusCode: {
            500: function (jqXHR, textStatus, errorThrown)  {
                console.log("Custom error : " + jqXHR.responseText + " Status: " + textStatus + " Http error:" + errorThrown);
            501: function (jqXHR, textStatus, errorThrown)  {
                console.log("Custom error : " + jqXHR.responseText + " Status: " + textStatus + " Http error:" + errorThrown);
            }
        })

statusCode: is useful when you want to call different functions for different status codes that you return from server.

You can see list of different Http Status codes here:Wikipedia

Additional resources:

  1. Returning Server-Side Errors from AJAX Calls
  2. Returning a JsonResult within the Error function of JQuery Ajax
  3. Handling Ajax errors with jQuery

Comments

2

When you return a bad request from Controller a global exception is triggered. Probably a error page is displayed in the client, so jquery get 200 response.

Solution 1:

Controller

[HttpPost]
public ActionResult FooAction(string id, string[] orderFields)
{
    bool hasError = true; //TODO: Validation

    if (hasError)
    {
       Response.Clear();
       Response.TrySkipIisCustomErrors = true; //the magic
       Response.StatusCode = (int)HttpStatusCode.InternalServerError;

       return Json(new { success = false, message = "test error", status = 500 });
    }
    else
    {
       return Json(new { success = true, message = "ok", status = 200 });
    }
}

View:

<script type="text/javascript">
    $.ajax({
        type: "POST",
        url: url,
        data: { orderFields: order },
        success: function (response) {
            if (response.success) {
                alert("Ok");
            }
        },
        error: function (xhr, status, error) {
            if (xhr.responseText != "") {
                var err = JSON.parse(xhr.responseText);
                if (err.status == 440) {
                    alert("Session expired");
                }
                else {
                    alert(err.message);
                }
            }
            else {
                alert("Crash");
            }
        }
    });
</script>



Solution 2: (More Elegant)
Create a custom attribute

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Net;
using System.Web.Mvc;

public class ExceptionJsonMvcAttribute : FilterAttribute, IExceptionFilter
{
    public virtual void OnException(ExceptionContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (context.Exception == null)
            return;

        int status;
        string message;
        var ex = context.Exception;
        var exceptionType = ex.GetType();
        if (exceptionType == typeof(UnauthorizedAccessException))
        {
            var exAccess = (UnauthorizedAccessException)ex;
            message = exAccess.Message;
            status = (int)HttpStatusCode.Unauthorized;
        }
        else if (exceptionType == typeof(SqlException))
        {
            var exSql = (SqlException)ex;
            message = GetDbMessage(exSql);
            status = (int)HttpStatusCode.BadRequest;
        }
        else if (exceptionType == typeof(KeyNotFoundException))
        {
            var exNotFound = (KeyNotFoundException)ex;
            message = exNotFound.Message;
            status = (int)HttpStatusCode.NotFound;
        }
        else
        {
            message = ex.Message;
            status = (int)HttpStatusCode.InternalServerError;
        }


        string json = ""; // TODO: Json(new { success = false, message = message, status = status });
        context.ExceptionHandled = true;
        context.HttpContext.Response.Clear();
        context.HttpContext.Response.TrySkipIisCustomErrors = true;
        context.HttpContext.Response.StatusCode = status;
        context.HttpContext.Response.ContentType = "application/json";
        context.HttpContext.Response.Write(json);
    }

    private string GetDbMessage(SqlException exSql)
    {
        //TODO: Remove generic from database

        return "DataBase Error see log";
    }
}

pay attention for ApiController use System.Net.Http instead of System.Web.Mvc


Controller:

[ExceptionJsonMvc]
[HttpPost]
public ActionResult FooAction(string id, string[] orderFields)
{
    bool hasError = true; //TODO: Validation

    if (hasError)
    {
       throw new Exception("test error");
    }
    else
    {
       return Json(new { success = true, message = "ok" });
    }
}

Comments

0

.Net Core version, which use the status code to represent server error

C# Code

public string methodName(int param1)
   {
   try{
        Response.StatusCode = 200;
        return "";
    }
   catch {
        Response.StatusCode = 400;
        return "";
        }
   }

ajax call:

 $.ajax({
 type: 'get',
 url: 'your url',
 data: {"param1":value1},
 success: function (data) {
    alert("success");
    },
  error: function () {
    alert("failed");
    }
 });

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.