I am building a .NET page for a project that adds a new City and State for a new user or updates the City and state if their ID is already in the database. Everything is working fine except for the fact that if a past user clicks submit to update their information, an entirely new entry is added to the database.
I have created the method already in the repository listed below.
public async Task<LocationViewModel> SaveLocationAsync(LocationViewModel model)
{
try
{
var location = new Location()
{
City = model.City,
State = model.State
};
if (model.Id != 0)
{
location.Id = model.Id;
}
_dbcontext.Location.AddOrUpdate(location);
await _dbcontext.SaveChangesAsync();
return model;
}
catch (Exception ex)
{
model.Error = true;
model.ErrorMessages = new List<string>()
{
string.Format("Something went wrong - Message: {0} \n Stack Trace: {1}", ex.Message,
ex.StackTrace)
};
return model;
}
}
I have also built a controller that saves and updates existing records asynchronously shown below.
[System.Web.Mvc.AllowAnonymous]
[System.Web.Http.HttpPost]
public async Task<LocationViewModel> SaveLocationApiAsync(LocationViewModel model)
{
var result = new LocationViewModel();
if (ModelState.IsValid)
{
result = await _locationRepository.SaveLocationAsync(model);
}
return result;
}
In addition, I have added added all of my routes and references.
Why is a new entry put in the database instead of the current one updating? The Javascript is shown below.
self.Submit = function () {
if (self.errors().length !== 0) {
self.errors.showAllMessages();
return;
}
if (isNumber(locationId)) {
self.Location().LocationId(locationId);
swal("Success", "Thank you for your submission \nYour information has been updated.", "success");
}
var newData = ko.mapping.toJSON(self.Location());
var url = "/Admin/SaveLocationApiAsync/Post/";
$.ajax({
url: url,
method: "POST",
data: newData,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
if (result.Error === true) {
swal("Error", result.ErrorMessages.join('\n'), "error");
} else {
//TOdo
}
},
error: function () {
swal("Error", "Something went wrong.\nPlease contact help.", "error");
}
});
};
I apologize if it is a lot. I have checked everything repeatedly and have fixed all bugs. I am out of ideas.
Thanks in advance.
Your url looks to the controller action seems incorrect. You have var url = "/Admin/SaveLocationApiAsync/Post/"; when it should be var url = "/Admin/SaveLocationApiAsync";
Another approach to getting the correct url would be:
var url = '#Url.Action("SaveLocationApiAsync", "<ControllerName>")';
Also, in your ajax error handler you can get the HTTP status code and error message, which would help.
error: function (jqXHR, textStatus, errorThrown) {
swal("Error", "Something went wrong.\nPlease contact help.", "error");
}
EDIT:
I should have prefaced that using Url.Action works when your JavaScript is in a view (assuming Razor view in this case).
Fiddler is great tool to use when debugging ajax calls.
Related
Hello wenn i want to send a post request to my Controller there is no data.
I tried to log my Json file and there is something. But when I send the post request my controller shows it is empty.
Here is my call:
var item = {};
var jsonObj = [];
item["ProductCategoryId"] = i;
item["Name"] = txtName;
item["Description"] = txtDescription;
item["Price"] = txtPrice;
item["Stock"] = txtStock;
item["ProductCategory"] = txtProductCategory;
item["Image"] = await getAsByteArray(txtImage);
jsonObj.push(item);
var jsonString = JSON.stringify(jsonObj);
console.log("jsonString : " + jsonString);
$.ajax({
url: "/Admin/SaveProductToDB",
type: "POST",
data: { dataToSend: jsonString},
success: function (data) {
if (data.status == "Success") {
BootstrapDialog.show({
title: 'Success!',
message: "Data Updated Successfully!",
buttons: [{
label: 'OK',
action: function (dialog) {
window.location.href = "/Admin/Product";
removeProdData(i);
$("#btnAddProd").attr("disabled",false);
dialog.close();
}
}]
});
}
}
});
//Here I make a breakpoint but my string is empty
public JsonResult SaveProductToDB(string dataToSend)
{
List<Product> _List = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Product>>(dataToSend);
}
the getAsByteArray
async function getAsByteArray(file) {
return new Uint8Array(await readFile(file))
}
function readFile(file) {
return new Promise((resolve, reject) => {
// Create file reader
let reader = new FileReader()
// Register event listeners
reader.addEventListener("loadend", e => resolve(e.target.result))
reader.addEventListener("error", reject)
// Read file
reader.readAsArrayBuffer(file)
})
}
I found out if I remove the Image. that the controller is then able to resize it. Thanks for the help so far. So I need to look at this place where the problem is.
You are checking against data.status as if it's a given that it exists. Just console.log(data) instead and you will see whether or not status is being returned.
Also, if you open the Network tab in Chrome you can click on the post request & see if your headers are going through accurately and also click on 'Preview' to see an unfiltered result from the controller.
You might want to modify your code to catch errors for debugging, ie:
$.ajax({
url: "/Admin/SaveProductToDB",
type: "POST",
data: { dataToSend: jsonString},
success: function (data) {
if (data.status == "Success") {
BootstrapDialog.show({
title: 'Success!',
message: "Data Updated Successfully!",
buttons: [{
label: 'OK',
action: function (dialog) {
window.location.href = "/Admin/Product";
removeProdData(i);
$("#btnAddProd").attr("disabled",false);
dialog.close();
}
}]
});
}
},
error:function (xhr, ajaxOptions, thrownError) {
// Set up whatever error reaction you want, here. ie:
console.log('An error was encountered.');
alert(xhr.status);
alert(thrownError);
}
});
Another tip is to validate empty data being submitted prior to the Ajax call, so you only touch the backend server when your data is valid - to avoid an error.
I am sending parameters to a stored procedure and the stored procedure return a message back, it's either a success or an error.
public IActionResult Index() => View();
public async Task<IActionResult> Upload(IFormFile file)
{
int cmdResponse = Convert.ToInt32(cmd.Parameters["#response"].Value);
string cmdMessage = cmd.Parameters["#message"].Value.ToString();
if (cmdResponse == 0)
{
con.Close();
return RedirectToAction("Index", Json(new { status = "error", message = cmdMessage }));
}
return RedirectToAction("Index", Json(new { status = "success", message = cmdMessage }));
}
and here is the view with the Javascript where I try to display the message from the stored procedure in an alert box.
<script>
$(function () {
$("#btn").click(function () {
dangerResponseMessage('btn');
});
});
function dangerResponseMessage(result) {
var url = window.rootUrl + 'Upload/Upload';
$.ajax({
type: "GET",
url: url,
dataType: 'json',
success: function (result) {
alert(result.message);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(result.message);
}
});
}
</script>
The problem is that the alert box displays undefined
and when I dismiss the alert, it return the message from the stored procedure in the URL in the browser.
The cyrillic sentence in the URL is the message I am trying to display in the alert box.
The ajax call is without data, since I don't need to send anything from the view to the controller.
Any ideas as why is it showing the message in the URL and not in the alert box?
Have you tried just console.log(result) to just confirm exactly what you're getting back? If you're code in failing in 'error', then does 'result exist? Looks like it belongs to 'success' which may also be why it's failing and showing up on the address bar.
I am new to developing a web application or website. Currently, I am working on the Login page, I want to redirect from Login to Index page. I am using c# on the server-side, I want to transfer after checking the credentials of the user in the DB. I tried Response.Redirect and Server.Transfer but it does not work. It always return this error on the Console of the Chrome Failed to load resource: the server responded with a status of 401 (Unauthorized) and when I click it, this is what inside.
System.InvalidOperationException: Parameter: users not found.
場所 System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection)
場所 System.Web.Services.Protocols.UrlParameterReader.Read(HttpRequest request)
場所 System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
場所 System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
This is my code on C#.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void LogMeIn(string users, string pass) {
try
{
string stmt = "SELECT COUNT(*) FROM tbllogin WHERE userName = #user AND passWord = #pass";
int count = 0;
using (MySqlConnection thisConnection = new MySqlConnection(connectionString()))
{
using (MySqlCommand cmdCount = new MySqlCommand(stmt, thisConnection))
{
cmdCount.Parameters.AddWithValue("#user", users);
cmdCount.Parameters.AddWithValue("#pass", pass);
thisConnection.Open();
count = Convert.ToInt32(cmdCount.ExecuteScalar());
if (count > 0)
{
HttpContext.Current.Response.Redirect("~/default/index.htm", false);
}
}
}
}
catch (ThreadAbortException tEx)
{
Console.WriteLine(tEx.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
And this is on Javascript.
function LoginMeIn(username, password) {
//var xdata = "{'users':'" + username.toString()
// + "','pass':'" + password.toString()
// + "'}";
var xdata = { "users": username.toString(), "pass": password.toString() };
console.log(xdata);
$.ajax({
type: "POST",
url: '../WebService/userLogin.asmx/LogMeIn',
data: JSON.stringify(xdata),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
},
error: function (e) {
// $("#divResult").html("Something Wrong.");
}
});
}
Any Help will be much appreciated. Thank you in advance and Regards.
You can use
return RedirectToAction("ActionName","ControllerName",Action Parameters)
You can see the documentation here
I´ve got a problem with my current mvc project.
I´m using an ajax call to send new comments to the server but the method does not even get called.
My js code:
$("#answer_button").click(function () {
showLoadingTab();
var actionUrl = '#Url.Action("AnswerThread", "Threads")';
var threadId = $("#threadId").val();
var msg = $("#answer_msg").val();
alert(actionUrl);
alert(msg);
alert(threadId);
$.ajax({
url: actionUrl,
type: "POST",
data: "Message=" + msg + "&threadId=" + threadId,
success: function (msg) {
hideLoadingTab();
location.reload();
},
error: function () {
alert("Ein Fehler ist aufgetreten.");
hideLoadingTab();
}
});
});
as you see I´ve alerted the url, msg and threadId and they are all correct. url: "/Threads/AnswerThread", msg: "test", threadId: 1.
I´ve already tried to put a breakpoint inside the AnswerThread method but it does not get called. The "AnswerThread" method is inside the "ThreadsController" and looks like this:
[HttpPost]
public ActionResult AnswerThread(string Message, int threadId)
{
var userId = User.Identity.GetUserId();
using (var db = new UnitOfWork(new BlogContext()))
{
db.Posts.Add(new Post()
{
Message = Message,
PublishTime = DateTime.Now,
ThreadId = threadId,
UserId = userId
});
db.Complete();
}
return PartialView("/Views/Partial/Clear.cshtml");
}
That´s exactly the same way I did it in the backend controllers but there it just works fine.
I hope somebody can help me..
UPDATE:
Made some changes just to try if any other way works.
Change1 js:
var data = {
threadId: threadId,
Message: msg
};
$.ajax({
url: actionUrl,
type: "POST",
content: "application/json; charset=utf-8",
dataType: "json",
data: data,
success: function (msg) {
if (msg.success == true) {
hideLoadingTab();
location.reload();
}
else
{
alert("Ein Fehler ist aufgetreten: " + msg.error);
}
},
error: function () {
alert("Ein Fehler ist aufgetreten.");
hideLoadingTab();
}
});
Change 2 c#:
[HttpPost]
public JsonResult AnswerThread([System.Web.Http.FromBody]PostDataModel data)
{
var userId = User.Identity.GetUserId();
string error = "";
bool success = false;
try
{
using (var db = new UnitOfWork(new BlogContext()))
{
db.Posts.Add(new Post()
{
Message = data.Message,
PublishTime = DateTime.Now,
ThreadId = data.threadId,
UserId = userId
});
success = true;
db.Complete();
}
}
catch(Exception ex)
{
error = ex.Message;
}
return Json(String.Format("'Success':'{0}', 'Error':'{1}'", success, error));
I tried this now with and without the "[FromBody]" statement.
Oh yes and I´ve added the DataModel like this:
public class PostDataModel
{
public int threadId { get; set; }
public string Message { get; set; }
}
and I also tried to manually configure the pointed route.
routes.MapRoute(
name: "AnswerThread",
url: "threads/answer",
defaults: new { controller = "Threads", action = "AnswerThread" }
);
The "actionUrl" variable in js get´s changed to /threads/answer but I´m always getting 500 Internal Server Error. When I put a breakpoint inside the method it does not stop at any point of the ajax call.
In the Chrome Dev Tools at the "Network" tab it says to me that there is a parameter called "id" which is null which causes to this 500 internal server error. I tried to find out more information about this but the error does not tell me where this parameter is located.
I´ve got no parameter called "id" inside this method or the data model so where does this come from?
Solution:
My Routes mapping was bad. I first mapped the route /threads/{id} and THEN did /threads/answer so when the /threads/answer got called it thought "answer" is an id so it tried to enter the "Index" method. So for my particular problem (and maybe for some other guys having the same issue) the solution was just to put the mapping of the /threads/answer route in front of the /threads/{id} route and it worked.
Please check your parameter types, in controller threadId is int type and from ajax call you are passing string type.
In Js
$("#answer_button").click(function () {
showLoadingTab();
var actionUrl = '#Url.Action("AnswerThread", "Home")';
var threadId = parseInt($("#threadId").val());
var msg = "Answer message";
alert(threadId);
$.ajax({
url: actionUrl,
type: "POST",
data: { Message: msg, threadId: threadId },
success: function (msg) {
hideLoadingTab();
location.reload();
},
error: function () {
alert("Ein Fehler ist aufgetreten.");
hideLoadingTab();
}
});
});
In Controller
[HttpPost]
public ActionResult AnswerThread(string Message, int threadId)
{
return Json("Data");
}
I am trying to POST to this Spring REST service that I have set up which will accept a Review object. I can easily test this in Java as I can create an actual Review object and it will successfully create into the database. The issue is when I am trying to do it in Javascript I get a 415 Unsupported Media Type error. I know this has to do with how I am creating my Review object in Javascript but I am not sure what I am doing wrong.
index.js code snippet
function submitReview() {
var rating = $('#rating-review input:radio:checked').val();
var newReview = new Review(Number($('#id-review').val()), rating, $('#message-text').val());
console.log(newReview);
$.ajax({
type: "POST",
url: baseUrl + "/review",
data: newReview,
success: function (response) {
if (response == 'success')
alert("Successfully submitted review");
else
alert("Unsuccessful Review Submission");
}
});
}
function Review(carId, rating, review)
{
this.carId = carId;
this.rating = rating;
this.review = review;
}
ReviewRestService.java code snippet
#POST
#Path("/review")
#Consumes(MediaType.APPLICATION_JSON)
public String addReview(Review review) {
reviewService.addReview(review);
return review.getId();
}
I have tried changing my submitReview() to be...
function submitReview() {
var newReview = {
"carId": 123,
"rating": 2,
"review": "testing"
};
$.ajax({
type: "POST",
url: baseUrl + "/review",
data: newReview,
success: function (response) {
if (response == 'success')
alert("Successfully submitted review");
else
alert("Unsuccessful Review Submission");
}
});
}
as a test, but I still receive the same error. Not sure what I am doing incorrectly.