I am writing an asp.net MVC application that will compliment another application that I have written. In my old application, I send errors from the controller to the client like so:
return new HttpStatusCodeResult(400, "Whatever went wrong.")
Then, on my client side the ajax error looks a little like this:
error: function (jqXHR, textStatus, errorThrown) {
redAlert(errorThrown);
}
This all works perfectly. Whatever message I put in on the controller side will pop up on the client side.
Now, I have tried to do the same thing with this new application. However, errorThrown has nothing in it every time.
I have no idea where to start looking so any help or guidance will be much appreciated.
Thanks!
EDIT 1
After talking through some stuff with Shyju, it seems that HttpStatusCodeResult is not sending the message back in the header in the new application. Still trying to work this out.
Edit 2
After some testing, I have found that the Custom Error message doesn't get sent through using SSL. Why would this be an issue and how can I solve this? I need to use SSL as the application requires Work Account Authentication.
When your server code returns a 400 bad request response from your web api controller, the message text you are sending will be in the response from the server as
{"Message":"Whatever went wrong."}
Now the $.ajax will use this response and create a js object from that and set it to the responseJSON property of the jqXHR object. So you may simply access that.
$.ajax({
url: 'yourApiEndpoint'
}).done(function (data) {
console.log(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
if (jqXHR.responseJSON) {
alert(jqXHR.responseJSON.Message);
}
});
When you return HttpStatusCodeResult from an MVC controller action method, IIS will return the markup for the 400 page. So the response is basically the HTML markup. The response headers will have the status code and the message and the $.ajax method will set the status message you send from server to the statusText property of the xhr object.
.fail(function (jqXHR, textStatus, errorThrown) {
if (jqXHR.statusText) {
alert(jqXHR.statusText);
}
});
Related
I am new to AngularJS and building a webpage that has a history table. When an action happens an entry is made in the database using a $http.post. Afterwards I want to retrieve the data from the database again and display it back in the table to show the new entry of the history being logged.
The issue I am having is that the post is called first and then the get, but the get happens before the insert can complete. How do I delay, or prevent the call to get the new data from the history until the post has completed?
Here are the $http calls I am making:
$http.post('http://MYSERVER/Service1.svc/insertImageHistory', {params: {JSON: parameters}}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
console.log(data);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log(data);
});
$http.get('http://MYSERVER/WcfService/Service1.svc/getImageHistory', {params: {DOC_ID: DOC_ID}})
.success(function (response){
$scope.InsImageHistory = response;
alert(JSON.stringify(response));
})
.error(function(data, status) {
console.error('Response error', status, data);
});
Thanks to the help from people on this site, I figured out how to make it work now. I changed my code to use .then for my first $http.post and inside the .then I called the #http.get like so:
$http.post('http://MYSERVER/Service1.svc/insertImageHistory', {params: {JSON: parameters}})
.then(function(data, status) {
$http.get('http://MYSERVER/WcfService/Service1.svc/getImageHistory', {params: {DOC_ID: DOC_ID}})
.success(function (response){
$scope.InsImageHistory = response;
//alert(JSON.stringify(response));
})
.error(function(data, status) {
console.error('Response error', status, data);
});
});
Hope this helps someone.
A bit more information on how you are posting your data to your end point (WCF API) would be helpful, but i'll assume you are making use of $http.
A basic http request in Angular looks like this:
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function (response) {
// this callback will be called asynchronously
// when the response is available
}, function (response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
As you can see in the above example, the $http service incorporates Promises. Once it receives a response from your WCF service request, it will hit the '.then' portion of the function. This allows you to run code after you receive a response from your Get/Post request.
You can include your code in the '.then' part of the request. This way when you receive a response back from the 'Insert' api method, you can be sure that the insert has completed, and you can call your 'refresh' GET api request thereafter.
Documentation for $http can be found here - $http Service
Documentation for Promises in angular $q can be found here - Promises $q
EDIT: Okay now that I have some more information I can advise further.
If I was you, I would Create an angular Service/Factory to wrap your functionality (Object Oriented Design). You can call it "ImageService". Create Functions such as Add, Get, Delete etc Which will wrap your $http methods.
I have created a really quick and simple Plunker for you here to see what I'm talking about: Angular Promises Plunker
I have the following basic code. I tried to debug this code but the javascript is very painful to debug, and I do not know where it is failing:
jQuery.support.cors = true;
var packet = {
Image: imageAsString,
PhnType: phoneType,
PhnMdl: phoneManufacturer
};
$.ajax({
url: "https://molecheckerservices2.azurewebsites.net/api/Testing/SubmitTestingData",
type: "POST",
dataType: "json",
data: JSON.stringify({ packet }),
success: function(data, textStatus, xhr) {
alert('yes');
window.localStorage.setItem("dataObject", JSON.stringify(data));
window.location = "results.html";
},
error: function (xhr, textStatus, errorThrown) {
alert('no');
window.localStorage.setItem("dataObject", JSON.stringify([.33, .33, .33]));
window.location = "results.html";
}
it gives me back an alert no, which corresponds with a failure. Additionally as I debug I see in my Javascript console that the error:
Failed to load resource: the server responded with a status of 400 (Bad Request)
Pops up. I tried to look up what this mean but I would be incredibly grateful for any problem specific advice!
Open up Fiddler and manually POST to your endpoint. If you do that, you will see the same error message I saw:
{"message":"No API version was specified in the request, this request needs to specify a ZUMO-API-VERSION of '2.0.0'. For more information and supported clients see: http://go.microsoft.com/fwlink/?LinkId=690568#2.0.0"}
It has a handy-dandy link in there for you. Also, here is a SO answer that possibly applies to you.
I did add the header mentioned above, resent the request and I received that sweet 200 response from your service, so I'm pretty sure that's your issue.
P.S. If you don't want random strangers inserting data into your app like I just did, you should secure your service or at least obfuscate the URL when mentioning it in public.
I have an application where I fetch a list of requests made by the user based on the idNo provided. The android application uses AJAX to make a request to a .NET WCF Service which in turn returns a IEnumerable of DTO for that request.
Following is the AJAX Code:
$.ajax({
url: baseURL + "RequestStatusList/"+idNo,
cache : false,
type : "GET",
dataType : "json",
contentType : "application/json; charset=utf-8",
crossdomain : true,
success : function(data, tst, xhr) {
//do something here
},
error: function (xhr, tst, err) {
alert(' Please Try Again ' + xhr.status);
}
});
A similar piece of code works in another page in the application, where only the process in success is different, rest all is same.
Here every time the request fails and enters the error section and displays undefined/0 as error. No details about error, hence i cannot get what maybe the problem.
When I debug the server side code I get proper value in the parameter passed and a IEnumerable is formed and returned. What fails is the client side code after successful execution of server code.
Please Help.
Thanks in advance.
dojo.xhrPost({
url: "Default.aspx/TestMethod",
handleAs: "json",
contentType: "application/json",
postData: dojo.toJson({ }),
load: function (result) {
debugger;
},
error: function (err) {
debugger;
}
});
That is the script I use to make a request to a WebMethod that is exposed in Default.aspx. The method is called TestMethod.
The error that I get is:
Unable to load Default.aspx/TestMethod status: 500
If you need any additional information please let me know.
*Note : I can call the method from the server side and it returns the results as intended.
I've been there. :(
Usually it is a problem with the format of the data that you are passing in. For instance, if your WebMethod has a parameter that is an int and you are passing a string, you will get a failure like this.
I would use a tool like Fiddler http://www.fiddler2.com/fiddler2/ to see what you are sending to the method.
Also turn on what ever server side logging and tracing that you have and use it. One source that is useful for 500 errors (which tend to happen before "your" server code is reached) is Asp.net health monitoring.
There is more info about setting that up and using it at http://msdn.microsoft.com/en-us/library/bb398933(v=vs.100).aspx
I'm trying to write a simple http server as a part of an application. It needs to respond to Http requests submitted with ajax on 127.0.0.1:someport with a simple text response. A javascript app will poll (or eventually longpoll) for information on the local users actions.
At the moment I've got an httpListener that calls the following as part of its callback processing:
private void ProcessRequest(HttpListenerContext context)
{
var stream = context.Response.OutputStream;
var resp = Encoding.UTF8.GetBytes("This is a test response" + DateTime.Now.ToShortTimeString() + "\r\n\r\n");
stream.Write(resp, 0, resp.Length);
stream.Close();
}
Which provides a result if called from the browser, but an error if called with $.ajax.
What is the minimum I need to return to get a sucess response to a query such as
$.ajax({
url: 'http://127.0.0.1:12345/',
dataType: 'text',
success: function (data) {
$('#res').html(data);
},
error: function(jqXHR, textStatus, errorThrown)
{
alert(textStatus);
}
}
);
Edit:
I believe I have avoided the cross site scripting issues by running
netsh http add urlacl url=http://*:12345/app user=domain\user
and can trace that the ProcessRequest is called
I suspect that your web service works fine. If you're calling it from a file URL, however, your document will not be able to call any URLs hosted under localhost:12345 because it's considered cross-domain. Try hosting the HTML and JavaScript under the same web site; you may see more success doing so.