Was wondering if someone can see what I can't see. The site is giving me an error of "http://localhost:XXXXX/Sales/Edit/[insert ID here] responded with a status of 400 (Bad Request)"
Here's my controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "")] Sale sale)
{
// Retrieve Part Number
Product product = await RetrieveProductUsingPartNumber(filter["ProductPartNumber"]);
// Validate Part Number
if (ValidateProduct(product)) s.ProductId = product.Id;
if (ModelState.IsValid)
{
salesRepository.Update(s);
await salesRepository.SaveAsync();
return Json(new SaleDtoWeb()
{
ProductPartNumber = s.Product.PartNumber
});
}
// Set response to error
Response.StatusCode = 400;
// Retrieve error messages
List<string> errors = RetrieveErrorMessages();
return Json(new { messages = errors });
}
Here's my POST
updateItem: function (item) {
return $.ajax({
type: "POST",
url: "Sales/Edit/" + item.Id,
data: AddAntiForgeryToken(item),
dataType: "json",
success: function (data) {
// Show Success message
showAlert('.alert-success', 'Successfully edited item');
// Hide Error alert
$('.alert-danger').hide();
},
error: function (data) {
var messages = JSON.parse(data.responseText);
// Format messages from server
var errorMessages = formatErrorMessages(messages['messages']);
// Show Error messages
showAlert('.alert-danger', errorMessages);
// Hide Success alert
$('.alert-success').hide();
}
});
}
EDIT: I've added the parameters/method signature to the controller. Mind you I didn't add the binded items because I want to focus on the just the PartNumber which is on another model/table
try adding:
Response.TrySkipIisCustomErrors = true;
It looks like your ModelState isn't valid. What does the controller method signature look like? Does it match what AddAntiForgeryToken(item) is passing?
What does the error message array tell you?
Related
In my view, I have an AJAX call which sends an id parameter to my controller. This bit works fine. In my controller, I plan to query the database with that id, pull out associated data and want to send this back to the AJAX call/view. This is the bit I am struggling with, as I am new to AJAX calls.
var chosenSchoolID = $("#SelectedSchoolId").val();
$.ajax({
url: "/Home/GetSchoolDetailsAJAX",
type: "POST",
data: {
schoolID: chosenSchoolID
},
dataType: "text",
success: function(data) {
if (data == "success") {
}
},
error: function(data) {
if (data == "failed")
alert("An error has occured!");
}
});
The above is my AJAX call, and this does hit my controller method. However in my controller, I want to now send back other string data and I am unsure on how to do this (just placeholder code currently)
[HttpPost]
public ActionResult GetSchoolDetailsAjax(string schoolID)
{
// query database using schoolID
// now we have other data such as:
string SchoolName = "";
string SchoolAddress = "";
string SchoolCity = "";
return null;
}
Must I declare variables in my Jquery and pass into the data parameter of the AJAX call in order for the values to be passed?
Many thanks in advance
The simplest way to do this is to return the entities retrieved from your database using return Json() from your controller.
Note that when retrieving data then a GET request should be made, not a POST. In addition the default MVC configuration should have the routes setup to allow you to provide the id of the required resource in the URL. As such, try this:
$.ajax({
url: "/Home/GetSchoolDetailsAJAX/" + $("#SelectedSchoolId").val(),
type: "get",
success: function(school) {
console.log(school);
},
error: function() {
alert("An error has occured!");
}
});
[HttpGet]
public ActionResult GetSchoolDetailsAjax(string id) {
var school = _yourDatabaseContext.Schools.Single(s => s.Id == id); // assuming EF
return Json(school);
}
If you'd like to test this without the database integration, amend the following line:
var school = new {
Id = id,
Name = "Hogwarts",
Address = "Street, City, Country"
};
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 trying to return a model in JSON form from a request sent as the following:
$(document).ready(function() {
(function(){
console.log("ran");
$.ajax({
type: "GET",
url: "https://clas.uconn.edu/Employees/Edit/22",
success: function(data) {
console.log("Success: " + data);
empData = data;
}
});
})();
});
My Controller for this method is:
// GET: Employees/Edit/5
public ActionResult Edit(int? id)
{
var id = employee.id;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (employee == null)
{
return HttpNotFound();
}
return new JsonResult() { Data = employee, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
Console.WriteLine("error");
}
However I am getting an entire html page in the consol log even though none of these controller actions return a view. Any ideas?
Edit:
After adding the datatype, I am getting an error in the console log saying:
GET http://localhost:59909/Employees/EmployeeLookupDisplay
net::ERR_CONNECTION_REFUSED
It is returning the entire page because there is an error in your request somewhere.
Add a block error to your ajax call and console.log on the xhr. You will get much more information about the error like this.
What you can try is making the request on POST and checking the properties of the context on the C# code. Sometimes adding dataType and the encoding helps for the request.
Additionally check for the returning status of your request on your browser developer tools. In chrome it is the network tab that shows all requests and their status.
Try This, but according to your code its always returning HTTP not foud which is HTML page. if you have data to employee. i mean your controller action getting success without any error. then you can try tis.
$.ajax({
type: "GET",
url: "https://clas.uconn.edu/Employees/Edit/22",
dataType: "json",
success: function(data) {
console.log("Success: " + data);
empData = data;
}
Maybe instead of returning new JsonResult() { Data = employee, JsonRequestBehavior = JsonRequestBehavior.AllowGet };, just return Json(employee, JsonRequestBehavior.AllowGet);'
Another thing i see:
on the first line you are doing var id = employee.id; -> where employee comes from? maybe the error is there.
I have a controller action like this (very simplified):
[HttpPost]
public JsonResult Submit()
{
Response.StatusCode = Convert.ToInt32(HttpStatusCode.BadRequest);
return new JsonResult
{
ContentEncoding = Encoding.Default,
ContentType = "application/json",
Data = new {error = "xxxxxxxxxx"}
};
}
The point is just that I want to return json, but the result in the browser is string.
Here is the property from the returned object:
To use this now, I have to do something like JSON.Parse, and I don't really want that. The controller action should just return json by itself.
I have previously seen a responseJSON property on the result object from the ajax request in JavaScript.
EDIT:
I'm using the jQuery form plugin, so technically it is that who makes the request.
Here is the code where I initialize the jQuery Form Plugin:
function initializeAjaxForm() {
var feedback = document.getElementById('feedback');
$('#upload-form').ajaxForm({
url: '/xxxx/Submit',
type: 'POST',
beforeSubmit: handleBeforeSubmit,
beforeSerialize: handlePreSerialize,
success: function (data) {
stopLoadingGif();
feedback.innerHTML = 'Yay!';
console.log(data);
},
error: function (data) {
debugger;
console.log(data);
stopLoadingGif();
feedback.innerHTML = 'Nay!';
}
});
}
Here is the request in the browser:
EDIT 2:
Here is the response headers:
EDIT3:
This only seems to be a problem in the error handler.
return JSON object not JSONResult like this:
return Json(new { error = "xxxxxxxxxx"},JsonRequestBehavior.AllowGet);
Have a look at this article
Hi I have this controller method
[HttpPost]
public JsonResult CalculateAndSaveToDB(BMICalculation CalculateModel)
{
if (ModelState.IsValid)
{
CalculateModel.Id = User.Identity.GetUserId();
CalculateModel.Date = System.DateTime.Now;
CalculateModel.BMICalc = CalculateModel.CalculateMyBMI(CalculateModel.Weight, CalculateModel.Height);
CalculateModel.BMIMeaning = CalculateModel.BMIInfo(CalculateModel.BMICalc);
db.BMICalculations.Add(CalculateModel);
db.SaveChanges();
}
var data = new
{
CalculatedBMI = CalculateModel.BMICalc,
CalculatedBMIMeaning = CalculateModel.BMIMeaning
};
return Json(data, JsonRequestBehavior.AllowGet);
}
And this is my JS functions:
$('#good').click(function () {
var request = new BMICalculation();
$.ajax({
url: "CalculateAndSaveToDB",
dataType: 'json',
contentType: "application/json",
type: "POST",
data: JSON.stringify(request), //Ahhh, much better
success: function (response) {
$("#result").text(response.result);
},
});
ShowBMI();
});
function ShowBMI() {
$.ajax({
type: "GET",
dataType: "json",
contentType: "application/json",
url: "CalculateAndSaveToDB",
success: function (data) {
var div = $('#ajaxDiv');
div.html("<br/> " + "<b>" + "Your BMI Calculations: " + "</b>");
printBMI(div, data);
}
});
};
When ShowBMI() is executed, Chrome says GET http://localhost:50279/BMICalculations/CalculateAndSaveToDB/0 404 (Not Found)
The POST works as it saves to the database etc but the GET doesn't? Is there any reason for this? As you can see the URLs are exactly the same in each JS function so Im not sure why its found once nut not again the second time?
UPDATE:
After separating logic, the values appearing on the webpage are both null. See below for code changes
[HttpPost]
public JsonResult CalculateAndSaveToDB(BMICalculation CalculateModel)
{
if (ModelState.IsValid)
{
CalculateModel.Id = User.Identity.GetUserId();
CalculateModel.Date = System.DateTime.Now;
CalculateModel.BMICalc = CalculateModel.CalculateMyBMI(CalculateModel.Weight, CalculateModel.Height);
CalculateModel.BMIMeaning = CalculateModel.BMIInfo(CalculateModel.BMICalc);
db.BMICalculations.Add(CalculateModel);
db.SaveChanges();
}
CalculateAndSaveToDB(CalculateModel.BMICalc.ToString(), CalculateModel.BMIMeaning.ToString());
return Json("", JsonRequestBehavior.AllowGet);
}
[HttpGet]
public JsonResult CalculateAndSaveToDB(string o, string t)
{
var data = new
{
CalculatedBMI = o,
CalculatedBMIMeaning = t
};
return Json(data, JsonRequestBehavior.AllowGet);
}
That's because you've applied the [HttpPost] attribute :) That attribute renders the action available solely for POSTing and not GETing. You should move the logic that is relevant for GETing to an action with the same name but without the [HttpPost] attribute and keep the logic for handling POSTed data in the action marked with the [HttpPost] attribute.
Be advised that you should reconsider the names when separating logic into different methods, or else the names will be misleading.
Regarding your update
I would have the POST request handling action (your action marked with HttpPost) return an ActionResult which in essence would mean that the POST request handling action upon successfully handling your request would redirect the user to a confirmation page or somewhere else. Wherever's preferable really :)
Try to approach it logically, what would be the natural chain of events upon POSTing the data? What would you as a user expect to happen?
Regarding your GET action, that is because you are not sending in the parameters o and t, which you then immediately return. Since nothing happens to these parameters in your logic and they are not otherwise specified, they will contain null which is the default value for variables of type string. Are you not intending to retrieve data from the database, rather than supply two parameters only to immediately return them?