Why is this basic json call not working? - ajax

The following JSON call always hits the AJAX error handler, and I can't figure out why:
$.ajax({
type: "GET",
url: '<%= Url.Action("MyTest", "Detail") %>',
dataType: "json",
error: function (xhr, status, error) {
alert(xhr + " | " + status + " | " + error);
},
success: function (json) {
alert(json);
}
});
All I get is Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://localhost:4497/Detail/MyTest?_=1320681138394
When I set a breakpoint in the controller, I can see that it's being reached, so I'm not sure where the request is falling down. Here's the action in the DetailController:
Function MyTest() As JsonResult
Return Json("Hello")
End Function
Any ideas?

The jQuery error handler is fired because it failed to parse the returned page as valid JSON. Since you get 500 internal server error, the page most likely doesn't contain valid JSON.
Load this page in your browser and fix it until it gives valid json:
http://localhost:4497/Detail/MyTest
After it is giving valid json in the browser, try the jQuery ajax call.
I have no idea of even the basic functionality of VB.NET but can you make so that the only thing that is printed on http://localhost:4497/Detail/MyTest is like:
print( '{"message":"hello"}' );
If the only thing the page is outputting is {"message":"hello"} then json error handler will not fire

Related

ajax call returning different datatypes?

I have the following ajax call:
$.ajax({
type: "post",
dataType: "html",
url: '#Url.Content("~/RBA/Tools/_Actions")',
data: $("#actionForm").serialize(),
success: function (response) {
debugger;
$("#DetailsEdit").removeClass('zoomInDown');
$("#DetailsEdit").addClass('flipInX');
$("#DetailsRefresh").html(response);
$("#actionPlaceholder").hide();
$("#dashSpinner").hide();
},
error: function (response) {
debugger;
$("#dashSpinner").hide();
swal({
title: "Error",
text: response.responseText,
type: "error",
showConfirmButton: true
});
}
});
I am having a problem with the error portion as it is returning html to me. When I run the MVC on my local machine, I am getting the error message displayed properly in a pop up box. When I deploy the application to another server, I am getting some lengthy html message which is really awkward. How do I fix this issue?
Here is my catch exception block of the controller that this ajax call is calling:
catch (Exception e)
{
log.Error(e);
if (e.Message.Contains("Is not a valid cause category."))
error = "The selected category is not a valid category. Please choose another category.";
else
error = "You cannot take this type of action.";
Response.StatusCode = 500;
return Json(error);
}
I know that my dataType in the ajax call is listed as html and I need the ajax call to return html when it is successful so that it can bring up another view. But in my error, I want to get a string so it can display the message to the sweetalert box. How do I accomplish this?
Thanks in advance
Use this:
return new HttpStatusCodeResult(500, error);
This will return a 500 INTERNAL SERVER ERROR result with your error message as the response body.
It may be necessary to include the following line of code to tell IIS to let you return 500:
Response.TrySkipIisCustomErrors = true

Calling partial view through AJAX in Asp.net MVC 5

I'm using the following code to call a partial view:
$('#btnGetMilestones').click(function () {
$.ajax({
url: "GetMilestones",
type: "get",
success: function (result) {
$('#milestonesContainer').html(result);
},
error: function (xhr, status, error) {
var msg = "Response failed with status: " + status + "</br>"
+ " Error: " + error;
$('#milestonesContainer').html(msg);
},
complete: function (xhr, status) {
var doneMsg = "Operation complete with status: " + status;
alert(doneMsg);
}
});
});
for this ActionResult:
public PartialViewResult GetMilestones()
{
return PartialView("_GetMilestones");
}
The partial view has the milestones for a project (milestones and project are models). When I call the partial view like this:
<div id="milestonesContainer">
#Html.Partial("_GetMilestones")
</div>
it works fine, it gets all the milestones for the project.
But when I try to call the partial view via ajax, the error gets called: Response failed with status: error
Error: Bad Request
I'm in the details view of a projects so the url is like this http://localhost:55623/Projects/Details/2002
I'm new in ajax and javascript, so please if possible, explain me like you do to a beginner.
UPDATE:
After getting some answer and playing around to find a solution, I understand why the error appears.
I'm inside the details view, so the url is like this: http://localhost:55623/Projects/Details/2002 see there is an ID parameter.
When I make the ajax call, the url is like this http://localhost:55623/Projects/Details without the id parameter. So in return I get a 400 error code
To build on my comment:
Sorry, I was being ambiguous with the term url. Here's what I meant:
Unless your currentl url in the browser is http://<hostname>/<Controller that contains GetMilestones>, your AJAX url is incorrect. The AJAX url needs to be /<Controller>/GetMilestones.
The beginning / takes you to the root of the project, then the rest is taken care of by your route config (typically /Controller/Method/Id). That's why the AJAX url usually needs to be /Controller/Method. However, if you are at the Index view, your url is typically http://<hostname>/Controller. So, if this is the case and your AJAX url is just Method, it will take you to http://<hostname>/Controller/Method since you didn't prepend your AJAX url with a /.
Instead of url: "GetMilestones", try using url: "#Url.Action("GetMilestones")" which will render the actual relative path of the action i.e. /{Controller}/GetMilestones.
Also ensure that you are referring to the correct file name in your controller, as in your view you refer to "_GetMilestone" and you say that works, but in your controller you reference "_GetMilestones" which would not resolve if your filename is indeed "_GetMilestone"
If you're getting a 500 error, that means it's likely that you're hitting the action and an exception is occurring before or while it renders the partial view. Try navigating directly to the partial view's action in your browser by typing localhost:port/Projects/GetMilestones and see if an exception page appears. Make sure you do something like this in the Configure method of your Startup class:
public void Configure (IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
}
You should consider taking advantage of the helper methods like Url.Action to generate the correct relative path to the action method you want to call via ajax. If you are js code is inside the view, you can simply call the method like
url: "#Url.Action("GetMilestones","Project")",
If it is in an external js file, you can still use the helper method to generate the path and set it to a variable which your external js file. Make sure to do javascript namespacing when you do so to avoid possible overwriting of js global variables.
so in your view/layout you can do this
<script>
var myApp = myApp || {};
myApp.Urls = myApp.Urls || {};
myApp.Urls.mileStoneUrl= '#Url.Action("GetMilestones","Project")';
</script>
<script src="~/Scripts/PageSpecificExternalJsFile.js"></script>
And in your PageSpecificExternalJsFile.js file, you can read it like
$(function(){
$('#btnGetMilestones').click(function () {
$.ajax({
url: myApp.Urls.mileStoneUrl,
//Your existing code goes here
})
});
});
You need to change first url to something that match the route:
'/<Controller>/GetMilestones/'
switch from PartialViewResult to ActionResult
go for ajax like:
url: "GetMilestones",
type: "get",
contentType: 'application/html; charset=utf-8',
dataType : 'html'
Thanks to all for answering. I got an answer for my problem, maybe it's kinda not expected. Her it is:
change the ajax method:
$('#btnGetMilestones').click(function () {
$.ajax({
url: '/Projects/GetMilestones/' + "?id=" + window.location.href.split('/').pop(),
type: "GET",
success: function (data) {
$('#milestonesContainer').html(data);
},
error: function (xhr, status, error) {
var msg = "Response failed with status: " + status + "</br>"
+ " Error: " + error;
$('#milestonesContainer').html(msg);
},
complete: function (xhr, status) {
var doneMsg = "Operation complete with status: " + status;
alert(doneMsg);
}
});
});
and the action result:
public ActionResult GetMilestones(int? id)
{
var forProject = db.Projects.Where(x => x.ID == id).SingleOrDefault();
return PartialView("_GetMilestones",forProject);
}
Or same action result but the ajax request slightly dirrent:
$('#btnGetMilestones').click(function () {
var id;
id = #Model.ID;
$.ajax({
url: '/Projects/GetMilestones',
type: "GET",
data: "id="+id,
success: function (data) {
$('#milestonesContainer').html(data);
},
error: function (xhr, status, error) {
var msg = "Response failed with status: " + status + "</br>"
+ " Error: " + error;
$('#milestonesContainer').html(msg);
},
complete: function (xhr, status) {
var doneMsg = "Operation complete with status: " + status;
alert(doneMsg);
}
});
});

Ajax get redirect url from 403 error

I'm making an ajax call to get a JSON response from the Soundcloud API. The issue I'm having is that some tracks are forbidden (error 403) to access. But I still want to obtain the URL where the GET request ended up at, since it holds the track id within it which I want to get. Here's the code:
function getSoundcloudId(url, callback) {
$.ajax({
type:"GET",
url: 'https://api.soundcloud.com/resolve.json?url=' + url + '&client_id=6d5bc62a483dce12f6f1d01bd93a0608',
dataType: "text",
success: function(data) {
var json = $.parseJSON(data);
callback(json);
},
complete: function(xhr, textstatus) {
console.log(textstatus);
},
error: function(jqXHR, status, error) {
console.log(jqXHR.getAllResponseHeaders());
},
});
}
I've been experimenting and trying to get the Location from the header which returns null and I cannot find anything within the xhr response that displays the new redirected URL. Where in the Chrome console it alerts me with the redirected url saying that the webpage I'm after is forbidden, I'm not sure if it's any help but it annoyed me seeing that it could find :P.
Chrome 403 Response with redirect URL
Do you get any information back from soundcloud?
It can sometimes be useful to just output the response and see what it says.
I had a quick look at their API, and it looks like you don't need to authenticate for simple GET requests.
I tried "https://api.soundcloud.com/tracks?client_id=6d5bc62a483dce12f6f1d01bd93a0608" in the browser and it gave me a nice response.
Are you sure what you are trying to do, doesn't require authentication?

Django - Ajax: sending url params in data

I am trying to send a "GET" and "POST" requests to Django server via Ajax.
First, I provide the URLConf:
url(r'^write_to_file/(?P<file_name>.*)/(?P<content>.*)/$',generalFunctions.write_to_file, name ='write_to_file'),
Now, the AJAX part. Previously, I used to do it this way (avoiding sending params in data)
$.ajax({
type: "GET",
url: '/write_to_file/' + file_name + '/' + content ,
data: {},
success: function(data){
alert ('OK');
},
error: function(){
alert("Could not write to server file " + file_name)
}
});
Up to a certain moment, I was satisfied by this method, but now it is important for me to pass on file_name and content via the "data" variable and for some reason I get 404 Error.
$.ajax({
type: "GET",
url: '/write_to_file/',
data: {'file_name':file_name, 'content':content},
success: function(data){
alert ('OK');
},
error: function(){
alert("Could not write to server file " + file_name)
}
});
Error on server-side:
Not Found: /write_to_file/
[15/Apr/2016 14:03:21] "GET /write_to_file/?file_name=my_file_name&content=my_content HTTP/1.1" 404 6662
Error on client-side:
jquery-2.1.1.min.js:4 GET http://127.0.0.1:8000/write_to_file/?file_name=my_file_name&content=my_content 404 (Not Found)
Any ideas why? Is it something wrong with the ajax syntax or it has somehow to do with the URLConf ?
url(r'^write_to_file/(?P<file_name>.*)/(?P<content>.*)/$',generalFunctions.write_to_file, name ='write_to_file'),
is now wrong, the url you are sending the post request to is: /write_to_file/
url(r'^write_to_file/$',generalFunctions.write_to_file, name ='write_to_file'),
is what you'd want i think!

Why won't jQuery call my Ajax error handler?

I have the following jQuery Ajax call (There are no other global settings/handlers):
$.ajax( {
url: "http://www.blah.com/url/does/not/exist",
type: "get",
data: someData,
dataType: "json",
error: function (xhr, msg, ex)
{
alert("Failed: " + msg);
},
complete: function (xhr, msg)
{
alert("Done: " + msg);
}
I would expect my error handler to be called, but instead the complete event fires and the alert displays Done: success. In my Javascript console, I see the following message:
XMLHttpRequest cannot load http://www.blah.com/url/does/not/exist.
Origin null is not allowed by Access-Control-Allow-Origin.
Why won't my error handler get called?
What is the meaning of the Origin message logged to the console?
Thanks!
Looks like the only way is to receive the server response in my success method and store it in a global variable, which I'll check in the handler for complete (which always gets called). No response means the request failed.
It's a shoddy way of handling errors in this otherwise excellent libary.
Your error handler isn't called because the AJAX request doesn't even take place: the browser refuses to do that because of the same origin policy: the data you're requesting would come from a different site than the one serving your page.
You can try using the JSONP data type to work around the problem:
$.ajax({
url: "http://www.blah.com/url/does/not/exist",
type: "get",
data: someData,
dataType: "jsonp",
error: function(xhr, msg, ex) {
alert("Failed: " + msg);
},
complete: function(xhr, msg) {
alert("Done: " + msg);
}
});

Resources