I want to parse JSON results, containing status or error messages, returned from controller method or custom exception filter and display the messages.
$.ajax({
url: "/Account/LogOn",
type: "POST",
dataType: "json",
data: form.serialize(),
success: function (result) {
alert(result);
}
});
I think that with this code I can do it for a specific Action Result or method. Is there a way to do this for every JSON result returned to the page?
No, there's no way to do this for every possible JSON returned by your controller actions because the structure will be different and the properties of this result variable won't be the same.
The correct way would be to have a custom error handler which will intercept all exceptions and wrap them in a well defined JSON structure. Then you could use the error callback in the AJAX request to handle this case.
public class AjaxErrorHandler : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.Result = new JsonResult
{
Data = new
{
ErrorMessage = filterContext.Exception.Message
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}
}
which could be registered as a global action filter:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AjaxErrorHandlerAttribute());
}
and on the client you could also have a global AJAX error handler for all AJAX requests on the same page:
$(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
var json = $.parseJSON(jqXHR.response);
alert(json.ErrorMessage);
});
$.ajax({
url: "/Account/LogOn",
type: "POST",
dataType: "json",
data: form.serialize(),
success: function (result) {
alert(result);
}
error: function (req, status, error) {
//your logic
}
});
Related
I don't know what I'm missing.
Everything works when passing complex custom objects, but when I try to pass a simple int or string I get null
Here is the ajax call on client side:
var id = 1;
$.ajax({
type: "GET",
url: "/api/APICalls/MethodName",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(id), // or JSON.stringify({id: id}) or just id
dataType: "json",
success: function (data) {
console.log(data);
},
error: function (data) {
alert(data.responseText);
}
});
On server side the method is as follows:
[HttpGet]
public void MethodName([FromBody] string id)
{
// Do something with id... Doesn't matter... It is `null`!
}
The reason why you are getting null value for id parameter is [FromBody]. Technically when you send GET request to the server with jQuery the data is presented in the query parameters and not in the request body.
What you need to do on backend side is just to remove [FromBody] as follows:
[HttpGet]
public void MethodName(string id)
{
// Now you should be able to access the value of id
}
Sending data from client side as the following:
var id = 1;
$.ajax({
url: '/api/APICalls/MethodName',
type: 'GET',
data: {id: id},
success: function (data) {
console.log(data);
},
error: function (err) {
console.error(err);
}
});
From the documentation for [FormBody] you can read the following:
To force Web API to read a simple type from the request body, add the [FromBody] attribute to the parameter.
Your data was presented in the query string, checking the network tab in Chrome:
I hope this helps!
I want to pass the variable from view to controller I am using ajax call to achieve it i am getting the error below. I don't know what i am missing here.
WARN 41440 --- [nio-8080-exec-9] o.s.web.servlet.PageNotFound : Request method 'POST' not supported
This is my code
document.getElementById('btntest').onclick = function(){
var selchbox = getSelectedChbox(this.form); // gets the array returned by getSelectedChbox()
myvalue = JSON.stringify(selchbox);
//document.write("check check"+selchbox);
$.ajax({
type: "POST",
url: "UserController/delete",
contentType: "application/json; charset=utf-8",
data: {key:myvalue},
cache: false,
success: function (data) {
alert("Are you sure?");
},
error: function (args) {
alert("Error on ajax post");
}
});
alert(selchbox);
}
My controller method looks like below
#RequestMapping(value = "/delete", method = RequestMethod.POST)
public String delete(#RequestBody String key) {
System.out.println("My Array value"+key.toString());
return key;
}
What i am missing here? Any Help
Finally i could able to pass the values from my view to controller I am posting the code.
This is my js code
document.getElementById('btntest').onclick = function(){
var selchbox = getSelectedChbox(this.form); // gets the array returned by getSelectedChbox()
var myvalue = JSON.stringify(selchbox);
//document.write("check check"+selchbox);
$.ajax({
type: "POST",
url: "/delete",
dataType : "JSON",
contentType:"application/json; charset=utf-8",
data: JSON.stringify(selchbox),
cache: false,
success: function (data) {
alert("Are you sure?");
},
error: function (args) {
alert("Error on ajax post");
}
});
alert(selchbox);
}
And my controller code
#RequestMapping(value = "/delete", method = RequestMethod.POST)
public String delete(#RequestBody String value){
System.out.println("My Array value"+value.toString());
return value;
}
First, if you want to delete, why not use the verb delete http?
I think you are not using the correct parameter: RequestParam is used to map your sORGID parameter to the URL (a parameter you did not use on the client side, you must use it or delete it).
If you want to map Json, you must use #RequestBody.
I hope it helps
At leaset two problems
url: "UserController/delete" in your ajax won't match "/delete/{sORGID}" in your controller.
data: {key:myvalue} in your ajax, the property name is key, in your controller it's myvalue[], this should also be the same.
I keep getting a 405 error upon a POST method
$.ajax({
url: mistergoUrl,
type: "POST",
dataType: "json",
data: body,
crossDomain: true,
contentType: "application/json",
success: function () {
// TODO: find a cleaner way to get the last route
$.getJSON(mistergoUrl)
.done(function (data) {
data = resolveReferences(data);
window.location.replace("Route.html?id=" + data.last().RouteId);
});
},
error: function (httpObj, result) {
Console.log(result);
Console.log(httpObj);
}
});
On the server, the request is valid, is processed and returned as expected, but the Ajax function keeps giving back a 405 error...
This is the asp.net code
[HttpPost]
public IHttpActionResult Post(RoutePostModel postdata)
{
if (!ModelState.IsValid)
{
return BadRequest();
}
_routeService.Add(postdata);
var route = _routeService.GetAll().Last();
var url = Url.Route("DefaultApi", new {controller = "Routes", id = route.RouteId});
return Created(url, route);
}
Does anybody know why and how this could happen? any help is appreciated!
So I have a basic controller accepting a post..
[HttpPost]
public ActionResult Submit(string postCost)
{
//Do stuff here before sending back redirect details...
return Json(new { result = "Redirect", url = Url.Action("Index", "Confirm") });
}
And I'm posting via jquery ajax method:
$.ajax({
url: partyURL,
dataType: 'json',
contentType: 'application/json', //charset=utf-8',
type: 'POST',
data: { postCost: postageCost}, //**This fails!**
//data: "{'postCost':'3.50'}", //**This works**
success: function (response) {
if (response.result == 'SoldOut') {
$("#soldOut").show();
}
else if (response.result == 'Redirect') {
//All good, onward to confirmation page
window.location = response.url;
}
},
error: function (xhr, status, error) {
// Error handling here
}
});
where the postageCost variable sent in when it fails returning status 500:
postageCost = '3.50';
postageCost = JSON.stringify(postageCost); //also fails with this
but if I hard-code the data definition as
data: "{'postCost':'3.50'}",
It works fine.
The key must therefore lie in what I'm doing with the data element?
you need to do
var datum = {'postCost': '3.50'};
data: JSON.stringify(datum), //Ajax call data
Hello everyone and thanks for your time.
Here is my javascript:
$('.sender').click(function (e) {
$.ajax({
type: "POST",
url: "fHandler.ashx",
data: { firstName: 'stack', lastName: 'overflow' },
// DO NOT SET CONTENT TYPE to json
// contentType: "application/json; charset=utf-8",
// DataType needs to stay, otherwise the response object
// will be treated as a single string
dataType: "json",
success: function (response) {
alert('success');
},
error: function (response) {
alert('error: ' + response);
console.log('err: '+response);
}
});
});
And here is the code in my .ashx handler:
public void ProcessRequest(HttpContext context)
{
context.Response.AppendHeader("Access-Control-Allow-Origin", "*");//to fix the allow origin problem
context.Response.ContentType = "text/plain";
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
context.Response.Write(json);
}
public bool IsReusable
{
get
{
return false;
}
}
While the click event is working, my Ajaxrequest doesn't seem to get any response as the alert at success doesn't popup. I've debugged using the browser's network console and it return the expected response but it doesn't seem to reach the success function in the JavaScript code. Any insights or suggestions are welcome. Thanks.
In case you are still interested in the answer, try this before doing the request
var data = { firstName: 'stack', lastName: 'overflow' };
var jsonData = JSON.stringify(data);
and change your AJAX request to
$.ajax({
type: "POST",
url: "fHandler.ashx",
data: jsonData,
dataType: 'json',
contentType: 'application/json; charset-utf-8'
})
.done(function (response) {
// do something nice
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.log("request error");
console.log(textStatus);
console.log(errorThrown);
});
Explanation
You are trying to send the plain data object. You must transform it into a Json string using JSON.stringify(object).
Changing the dataType isn't really a solution but a workaround.
Additional Notes
Also, I think you should use .done() and .fail(). See here for further details.