I want to display in a webpage an exception message raised in my .NET code in the error part of an ajax request:
[HttpPost]
[AllowAnonymous]
public virtual ActionResult AuthenticateUser(string somedata)
{
throw new Exception("Ooops!!");
}
JS code:
jQuery(document).ready(function () {
jQuery.ajax(
'#Url.Action("AuthenticateUser")',
{
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {
somedata:somedata
},
success: function (result) {
if (result == 'true') {
window.location = '#Url.Content(Request["returnUrl"])';
}
},
error: function (response) {
var responseJson = jQuery.parseJSON(response.responseText);
$('#errorMessage').text(responseJson.Message);
$('#progress_message').text("");
},
type: 'post'
}
);
});
The error I get in "response" is HTML code and I want to parse it to get the exception message I throw from the server side. So, the better approach I came up with was to return a Json response, but despite specifying "json" as datatype I still receive HTML code in "response", so... what am I doing wrong? Is the problem the "Exception" object I throw from the server side?
The problem is that whenever an exception is thrown in a controller, it will always trigger asp.net's error page and return whatever is configured for the 500 http status code (the default result is the "yellow page of death" which is an html), what you are trying to do is custom error handling and there are several ways of doing it in depth explanation is present in this blog
One way you could do this is by overriding the OnException method:
protected override void OnException(ExceptionContext filterContext)
{
filterContext.Result = Json(new {Message = filterContext.Exception.Message});
filterContext.ExceptionHandled = true;
}
This will replace the default result for an internal server error (500) with a json result containing the error message, which can be obtained like below
jQuery.ajax(
'#Url.Action("AuthenticateUser")',
{
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
console.log(result);
},
error: function (response) {
var responseJson = jQuery.parseJSON(response.responseText);
console.log(responseJson.Message); //Logs the exception message
},
type: 'post'
});
This will catch errors Controller wise, if you want to do this application wise you will have to go a little deeper on the blog's methods (probably with the "HandleError" Attribute)
In the end I returned JsonResults and handled the message from the view:
Server code:
[HttpPost]
[AllowAnonymous]
public virtual JsonResult AuthenticateUser(string somedata)
{
if (ok)
return new JsonResult() {Data="ok"}
return new JsonResult() {Data= "Missing data blah"}
}
And in javascript:
success: function (result) {
if (result == 'ok') {
window.location = '#Url.Content(Request["returnUrl"])';
return;
}
$('#progress_message').text("");
$('#errorMessage').text(result);
},
Related
I have an Ajax Call and a Controller with some methods and there is something weird.
The Ajax call can reach the Controller Method. The method is returning the value perfectly, no errors, nothing. However, in the AJAX the return is coming with error (not on success of Ajax).
Moreover, If I inspect the return I can see the correct values on responseJson, but the status is 404 and statusText is "error" ({"readyState":4,"status":404,"statusText":"error"})
Anyone have an idea what is going on? There is no error in backend, however error in Ajax.
Controller Method
public JsonResult SceneListUpdated(string sceneId)
{
SceneListModel model = new SceneListModel();
var licenseValidationState = KeygenLicenseState.CheckLicense();
if (licenseValidationState == 0)
{
SceneListService sceneService = new SceneListService();
model = sceneService.GetSceneListUpdated(sceneId);
return Json(new { Success = true, data = model }, JsonRequestBehavior.AllowGet );
}
return Json(new { Success = false, data = "" }, JsonRequestBehavior.AllowGet);
}
Ajax Function
$.ajax({
url: "/api/test/SceneList/SceneListUpdated?sceneId=" + sceneIdAux, //Method in controller
type: "GET",
contentType: "application/json; charset=utf-8",
datatype: "json",
success: function (e) {
},
error: function (data) {
}
});
try to fix the ajax
$.ajax({
url: "/api/test/SceneList/SceneListUpdated/"+ sceneIdAux, //Method in controller
type: "GET",
success: function (e) {
},
error: function (data) {
}
});
and maybe you can try one of these routing since you have 404
[Route("{sceneId}")]
[Route("~/api/SceneList/SceneListUpdated/{sceneId}")]
public JsonResult SceneListUpdated(string sceneId)
I'm wondering how to display a succes or error message on succes or fail by a controller action in my MVC project with bootstrap. For example I got the following action:
Input:
Javascript method to send data to controller:
//Sends data filled in in modal to backend.
$(document).ready(function () {
$("#btnSubmit").click(function () {
var datastring = $("#myForm").serialize();
$.ajax({
type: "POST",
url: "/ApiBroker/AddApi",
dataType: 'json',
data: datastring,
});
$('#myModal').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
})
})
Controller method:
[HttpPost]
public ActionResult AddApi(ApiRedirect model)
{
var data = model;
try
{
List<ApiRedirect> list = dbProducts.ApiRedirects.ToList();
int companyID = dbProducts.Companies.Where(x => x.CompanyName == model.Company.CompanyName).FirstOrDefault().CompanyID;
int mappingID = dbProducts.MappingNames.Where(x => x.Name == model.MappingName.Name).FirstOrDefault().MappingID;
ApiRedirect api = new ApiRedirect();
api.ApiName = model.ApiName;
api.CompanyID = companyID;
api.ApiURL2 = model.ApiURL2;
api.MappingID = mappingID;
api.ResponseType = model.ResponseType;
dbProducts.ApiRedirects.Add(api);
dbProducts.SaveChanges();
return View ();
}
catch (Exception ex){
throw ex;
}
}
If the method AddUser added the user into my database I want to display a error message, and if the user was not added I want to display a error message. I dont know how to achieve this, any suggetions?
Thanks in advance!
UPDATE
So the alert works but the POST call is getting the following internal server error:
Firstly you ajax needs to be updated to use a success or failure
$.ajax({
type: 'POST',
url: "/ApiBroker/AddApi",
data: datastring,
dataType: 'json',
success:
function(data){
//... put your logic here
},
error:
function(){ alert('error'); }
});
Secondly you need to update your controller action to return a IHttpActionResult where you can specify a Response message.
If you look at this
HttpResponseMessage
I am realy struggling with this and would apprecate any advice.
I have this field
<input id="scanInput" type="text" placeholder="SCAN" class="form-control" />
For which I would like to make an ajax call when the field changes, so I tried
<script>
$("#scanInput").change(function () {
console.log('ye');
$.getJSON("?handler=GetPartDetails", function (data) {
//Do something with the data.
console.log('yay?');
}).fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log("Request Failed: " + err);
});
});
</script>
Where my PageModel has this method
[HttpPost]
public IActionResult GetPartDetails()
{
return new JsonResult("hello");
}
and the url for the page in question is /packing/package/{id}
Now when I change the input value, I see ye on the console, and I can see that the network called http://localhost:7601/Packing/Package/40?handler=GetPartDetails (the correct URL I think?) with status code 200
But My breakpoint in GetPartDetails never hits, and I don't see yay? in the console.
I also see this message from the fail handler:
Request Failed: parsererror, SyntaxError: JSON.parse: unexpected character at line 3 column 1 of the JSON data
But I'm not even passing any JSON data... why must it do this
I also tried this way :
$.ajax({
type: "POST",
url: "?handler=GetPartDetails",
contentType : "application/json",
dataType: "json"
})
but I get
XML Parsing Error: no element found
Location: http://localhost:7601/Packing/Package/40?handler=GetPartDetails
Line Number 1, Column 1:
I also tried
$.ajax({
url: '/?handler=Filter',
data: {
data: "input"
},
error: function (ts) { alert(ts.responseText) }
})
.done(function (result) {
console.log('done')
}).fail(function (data) {
console.log('fail')
});
with Action
public JsonResult OnGetFilter(string data)
{
return new JsonResult("result");
}
but here I see the result text in the console but my breakpoint never hits the action and there are no network errors..............
What am I doing wrong?
Excuse me for posting this answer, I'd rather do this in the comment section, but I don't have the privilege yet.
Shouldn't your PageModel look like this ?
[HttpPost]
public IActionResult GetPartDetails() {
return new JsonResult {
Text = "text", Value = "value"
};
}
Somehow I found a setup that works but I have no idea why..
PageModel
[HttpGet]
public IActionResult OnGetPart(string input)
{
var bellNumber = input.Split('_')[1];
var partDetail = _context.Parts.FirstOrDefault(p => p.BellNumber == bellNumber);
return new JsonResult(partDetail);
}
Razor Page
$.ajax({
type: 'GET',
url: "/Packing/Package/" + #Model.Package.Id,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {
input: barcode,
handler: 'Part'
},
success: function (datas) {
console.log('success');
$('#partDescription').html(datas.description);
}
});
For this issue, it is related with the Razor page handler. For default handler routing.
Handler methods for HTTP verbs ("unnamed" handler methods) follow a
convention: On[Async] (appending Async is optional but
recommended for async methods).
For your original post, to make it work with steps below:
Change GetPartDetails to OnGetPartDetails which handler is PartDetails and http verb is Get.
Remove [HttpPost] which already define the Get verb by OnGet.
Client Request
#section Scripts{
<script type="text/javascript">
$(document).ready(function(){
$("#scanInput").change(function () {
console.log('ye');
$.getJSON("?handler=PartDetails", function (data) {
//Do something with the data.
console.log('yay?');
}).fail(function (jqxhr, textStatus, error) {
var err = textStatus + ", " + error;
console.log("Request Failed: " + err);
});
});
});
</script>
}
You also could custom above rule by follow the above link to replace the default page app model provider
I'm working on a webapplication, ASP.Net MVC 4.0 with entityframework 6.0, trying to update database as per user selection. Data is sent to controller's action using jQuery AJAX. Below given is C# code to update entity which in turn updates database.
public void modidyProduct(Productdetail prodData)
{
try
{
using (SampleTrialEntities entity = new SampleTrialEntities())
{
var data = entity.Productdetails.Where(p=>p.ProductID == prodData.ProductID).FirstOrDefault<Productdetail>();
data.ProductName = prodData.ProductName;
data.ProductNumber = prodData.ProductNumber;
data.CategoryName = prodData.CategoryName;
data.ModelName = prodData.ModelName;
entity.Entry(data).State = System.Data.Entity.EntityState.Modified;
entity.SaveChanges();
}
}
catch (Exception)
{}
}
And here's jQuery AJAX call for that controller action method.
function updateProduct() {
var productData = {
ProductName: $('#prodName').val().trim(),
ProductNumber: $('#prodNum').val().trim(),
CategoryName: $('#ctgryName :selected').text(),
ModelName: $('#mdlName :selected').text(),
ProductID: atob($('#editProductId').val())
};
debugger;
$('#divLoader').show();
$.ajax({
url: '#Url.Action("modidyProduct", "Home")',
data: JSON.stringify(productData),
type: 'POST',
dataType: 'json',
contentType: 'application/json;charset=utf-8',
success: function (jqXHR) {
//Below line will destroy DataTable - tblProducts. So that we could bind table again. next line - loadData();
$('#tblProducts').DataTable().destroy();
$('#divLoader').hide();
loadData();
$('#addModal').modal('hide');
$('#editProductId').val('');
},
error: function (msg) {
debugger;
$('#editProductId').val('');
$('#divLoader').hide();
alert(msg);
alert("What's going wrong ?");
//alert(jqXHR.responseText);
}
});
}
After executing jQuery AJAX method & controllers action, successfully updates the record in database. Response statuscode - 200 & Status - OK is returned. But only error: { }, code block is executed every time in AJAX method.
Debugging screen capture with status-OK; statuscode - 200
This part of your $.ajax method call
dataType: 'json',
It tells jQuery that, the ajax call code is expecting a valid JSON response back but currently your server method's return type is void. That means it won't return anything and the $.ajax method is trying to parse the response (assuming it is a valid JSON), and hence getting the typical "parsererror"
When the datatype is json and the response is received from the server, the data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected.
The solution is to simply remove the dataType property in the call.
$.ajax({
url: '#Url.Action("modidyProduct", "Home")',
data: JSON.stringify(productData),
type: 'POST',
contentType: 'application/json;charset=utf-8'
}).done(function() {
console.log('Success');
})
.fail(function(e, s, t) {
console.log('Failed');
});
Or you can update your server action method to return a json response.
[HttpPost]
public ActionResult ModidyProduct(Productdetail prodData)
{
try
{
//to do : Save
}
catch (Exception ex)
{
//to do : Log the exception
return Json(new { status = "error", message=ex.Message });
}
return Json(new { status="success"});
}
Now in your client side code, you can check the json response to see if the transaction was successful
$.ajax({
url: '#Url.Action("ModidyProduct", "Home")',
data: JSON.stringify(productData),
type: 'POST',
contentType: 'application/json;charset=utf-8',
dataType: 'json',
}).done(function (res) {
if (res.status === 'success') {
alert('success');
} else {
alert(res.message);
}
console.log('Success');
}).fail(function(e, s, t) {
console.log('Failed');
});
You do not need to necessarily specify the dataType property value. If nothing is specified jQuery will try to infer it based on the mime type of the response coming back, in this case, the response content type will be application/json; charset=utf-8. So you should be good.
UpdateModule is a function used for update module details. It's not a view page.
When click on update, it returns 500 (internal server error) or 404 error
please help to fix it
$.ajax({
type: 'POST',
url: '#Url.Action("ETM_PRODUCTS","UpdateModule")',
//contentType: 'application/json',
datatype: JSON,
data: { 'ModuleID': ModuleID, 'ModuleName': ModuleName, 'ModuleDescription': ModuleDescription },
success: function (data) {
if (data == true) {
alert("Updated Successfully");
}
},
error: function (msg) {
alert("Error")
},
});
c#
public JsonResult UpdateModule(int ModuleID,string ModuleName,string ModuleDescription) {
bool status = true;
PROD_MODULE tabledata = db.PROD_MODULE.Where(x => x.ETM_MODULE_ID == ModuleID)
.FirstOrDefault();
tabledata.NAME = ModuleName;
tabledata.DESCRIPTION = ModuleDescription;
db.SaveChanges();
return Json ( status, JsonRequestBehavior.AllowGet );
}
There is a problem in the way you call Url.Action.
The first parameter is the action and the second the controller.
Here is the documentation : link