Reputation: 109
I am new to .NET MVC so please bear with me.
I wrote a function that gets triggered when there is a blur action on the textarea control:
function extractURLInfo(url) {
$.ajax({
url: "/Popup/Url",
type: "POST",
data: { url: url },
complete: function (data) {
alert(data);
},
success: function (data) {
alert(data);
},
async: true
})
.done(function (r) {
$("#url-extracts").html(r);
});
}
jQuery(document).ready(function ($) {
$("#input-post-url").blur(function () {
extractURLInfo(this.value);
});
});
This works fine and will hit the controller:
[HttpPost]
public ActionResult Url(string url)
{
UrlCrawler crawler = new UrlCrawler();
if (crawler.IsValidUrl(url))
{
MasterModel model = new MasterModel();
model.NewPostModel = new NewPostModel();
return PartialView("~/Views/Shared/Partials/_ModalURLPartial.cshtml", model);
}
else
{
return Json(new { valid = false, message = "This URL is not valid." }, JsonRequestBehavior.AllowGet);
}
}
I get the intended results if the URL is valid; it will return a partialview to the .done() function and I just display it in code. However, if the URL is not valid i want it to hit either complete, success, or done (I have been playing around to see which it will hit but no luck!) and do something with the returned data. I had it at some point trigger either complete or success but the data was 'undefined'. Can someone help me out on this?
Thanks!
Upvotes: 0
Views: 2614
Reputation: 1038720
In both cases your controller action is returning 200 status code, so it's gonna hit your success
callback:
$.ajax({
url: "/Popup/Url",
type: "POST",
data: { url: url },
success: function (data) {
if (data.message) {
// Your controller action return a JSON result with an error message
// => display that message to the user
alert(data.message);
} else {
// Your controller action returned a text/html partial view
// => inject this partial to the desired portion of your DOM
$('#url-extracts').html(data);
}
}
});
But of course a much better and semantically correct approach is to set the proper status code when errors occur instead of just returning some 200 status code:
[HttpPost]
public ActionResult Url(string url)
{
UrlCrawler crawler = new UrlCrawler();
if (crawler.IsValidUrl(url))
{
MasterModel model = new MasterModel();
model.NewPostModel = new NewPostModel();
return PartialView("~/Views/Shared/Partials/_ModalURLPartial.cshtml", model);
}
else
{
Response.StatusCode = 400;
Response.TrySkipIisCustomErrors = true;
return Json(new { valid = false, message = "This URL is not valid." }, JsonRequestBehavior.AllowGet);
}
}
and then in your AJAX call you would handle those cases appropriately:
$.ajax({
url: "/Popup/Url",
type: "POST",
data: { url: url },
success: function (data) {
$('#url-extracts').html(data);
},
error: function(xhr) {
if (xhr.status == 400) {
// The server returned Bad Request status code
// => we could parse the JSON result
var data = JSON.parse(xhr.responseText);
// and display the error message to the user
alert(data.message);
}
}
});
Also don't forget that you have some standard way of returning your error messages you could subscribe to a global .ajaxError()
handler in jQuery instead of placing this code in all your AJAX requests.
Upvotes: 2