Jquery Ajax, return success/error from mvc.net controller

Jqueryasp.net Mvc

Jquery Problem Overview


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);     
    
               }   
    
            }

Jquery Solutions


Solution 1 - Jquery

 $.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!"); 
                }
            });

Solution 2 - Jquery

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',

Solution 3 - Jquery

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

Solution 4 - Jquery

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" });
	}
}

Solution 5 - Jquery

.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");
    }
 });

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEyalView Question on Stackoverflow
Solution 1 - JqueryEyalView Answer on Stackoverflow
Solution 2 - JquerySBirthareView Answer on Stackoverflow
Solution 3 - JqueryTekinView Answer on Stackoverflow
Solution 4 - JqueryLucio PelinsonView Answer on Stackoverflow
Solution 5 - JqueryPrashSEView Answer on Stackoverflow