setFullResponse does NOT return ASP.Net HTTPResponseMessage Content
CodeLiftSleep opened this issue · 7 comments
After trying all kinds of methods, I STILL cannot get the content to return from my ASP.Net API...
I have the following RestangularProvider set up...the enabling of the setFullResponse gives me NO other pertinent information but does now require me to return response.data instead of response...
I would assume the data = "" should be where the content message should be getting returned but it doesn't. I only have the Status Code and status text. I have custom messages I am sending back from my API that are not able to be displayed because there is nowhere to retrieve them from...this is a pretty big problem. I am catching an error don't you think it might be kind of important to know what the error is from the returning API?
Here is an example in the API of what is being intercepted:
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest) { Content = new StringContent(ex.Message.ToString()) };
Here is the restangularProvider configuration:
.config(function (RestangularProvider) {
RestangularProvider.setFullResponse(true);
RestangularProvider.setBaseUrl('http://localhost/xxxxxxx/');
RestangularProvider.setErrorInterceptor(function (response, deferred, responseHandler) {
alertify.error("Error! " + response.statusText + " : " + response.status);
return true;
});
})
Where do I get the Content message from?
Have you tested your API with Postman or similar tools? Does it return the correct (raw) response in the first place? Is the HTTP status code correct? I.e. can you rule out the possibility that the problem is in your API and not in Restangular?
It doesn't return...the only time it ever returns an object in the data is when I have an UNCAUGHT exception because in ASP.net those return a data object----when we catch the exception and return an HTTPResponseMessage, that returns a Content object, not a data object, so the data object remains "" and does nothing for us.
Restangular really should add in a content object to the setErrorInterceptor to allow for use with HTTPResponseMessages, as that is what they return, not a data object...
We handled it client side by using else-if statements in RestangularProvider, but IMHO that is a poor design if that is how its supposed to be.
This is from
catch (Exception ex)
{
return new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest) { Content = new StringContent(ex.InnerException.ToString()) };
}
And this is the response from NOT Handling the exception and letting it error out...
{"Message":"An error has occurred.","ExceptionMessage":"An error occurred while updating the entries. See the inner exception for details.","ExceptionType":"System.Data.Entity.Infrastructure.DbUpdateException","StackTrace":" at ....}
which is more like what I would expect to see it return as a JSON object...and this is the preview of it:
Ok, so when you don't catch the exception in the backend, the browser gets some JSON with messages. This makes sense since you're probably developing a JSON API and your ASP backend apparently defaults to some generic error format in JSON when an exception occurs.
When you catch the exception, you return the InnerException object as a string. Here you seem to have two problems:
- You're not returning JSON. You're API is a JSON API and error responses should also be returned as JSON, just as the uncaught (automatically generated) exception is. Fix this.
- You're returning the whole InnerException object as a String. The InnerException is an object consisting of Exception Message, ExceptionType, InnerException, Message, and StackTrace. This seems to get cast into one giant String, which is probably not what you want. Instead just return something like
ex.InnerException.ExceptionMessage
. As JSON.
If you fix your backend to return some sensible JSON, for example:
{
"message": "An exception has occurred"
}
You will see that the Restangular ErrorInterceptor will work as expected.
I made a Plunker demonstrating this: http://plnkr.co/edit/Cy4AMC?p=preview
Open the Network tab to see what's going on. When you press the button the server responds with a HTTP 400 and the response body is JSON { "message" : "Invalid objects: state should be: count"}
.
Open the Console to see what my code is outputting. In both the ErrorInterceptor and the reject handling function response.data.message
will be "Invalid objects: state should be: count".
Hope this helps.
And in the future, please consider posting questions regarding Restangular usage on StackOverflow instead :) You'll get quicker responses over there!
Hmm...I'm I'll have to see how to do that...we are using ASP.net MVC as the backend...
So I would need to make sure it contains a "data" array with an array of objects inside that for it to work properly? When I send over an HTTPResponseMessage it contains a "Content" Object, not a "Data" Object...an unhandled exception however DOES contain a "Data" object rather than a "Content" Object....
so Restangular would need to look for a Content Object otherwise
Your response can contain whatever information you want, as long as it's valid JSON. The full JSON response payload will be available in the response.data
object in the ErrorInterceptor, you don't need a data
property in your response object for that.
Looking at your screenshot from the response object you're method is sending, it contains no valid JSON, only plain text. In your code you have a variable called Content
, but that doesn't seem to produce any Content
named counterpart in the response, and frankly I don't see how it would (although I don't know anything about ASP.NET so I might be wrong).
You need to get your backend in order, and this is not the right forum for you to learn that. It seems you need to read up on how to produce a JSON API with ASP.NET, which is not Restangular's headache. Make your API produce valid JSON and Restangular will play along nicely.
Over and out.