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.
Related
I'm trying to get user email from ASP.NET Web API through writing an email in an input box using JQuery (to select message recipients), But the returned value is null. Are there any problems in passing process in my code?
Web API:
[AllowAnonymous]
[HttpGet]
[Route("get-reciver-email")]
public ApplicationUser GetReciverEmailId([FromUri] string email)
{
return _userManager.FindByEmail(email);
}
Client-side "JQuery":
$('#toEmail').keyup(function () {
$.ajax({
url: '/api/Account/get-reciver-email/' + $("#toEmail").val(),
method: 'GET',
success: function (response) {
console.log(response);
},
// Display errors if any in the Bootstrap alert <div>
error: function (jqXHR) {
$('#divErrorText').text(jqXHR.responseText);
$('#divError').show('fade');
}
});
});
I expect to return user info based on passed email in HTML form.
Solved.
I removed [FromUri] & I used query-string (THX for #Mihai), also I modified API function to the following:
[AllowAnonymous]
[HttpGet]
[Route("get-reciver-email")]
public string GetReciverEmailId(string email)
{
return db.Users.Where(x => x.Email == email).Select(x => x.Id).Single();
}
Client-side code:
$('#toEmail').keyup(function () {
$.ajax({
url: '/api/Account/get-reciver-email/?email=' + $("#toEmail").val(),
method: 'GET',
success: function (response) {
console.log(response);
},
// Display errors if any in the Bootstrap alert <div>
error: function (jqXHR) {
$('#divErrorText').text(jqXHR.responseText);
$('#divError').show('fade');
}
});
});
I have a Javascript function I am calling from C# code behind when a user clicks an OnRowDeleting call from a GridView. Here is that Call and method
OnRowDeleting="GridView1_RowDeleting"
protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
ClientScript.RegisterStartupScript(GetType(), "hwa", "Ealert();", true);
}
It then calls that JS code and asks a question to the user. Based on whether they hit yes or no. I need it the JS to send a call to a C# method. Here is the JS code and the C# code that it is supposed to call.
<script> ...JS..
function Ealert() {
//var test = document.getElementById("hdField");
bootbox.confirm({
message: "Did you send the renewal email associated with this client?",
buttons: {
confirm: {
label: 'Yes',
className: 'btn-success'
},
cancel: {
label: 'No',
className: 'btn-danger'
}
},
callback: function (result) {
if (result == true) {
bootbox.alert({
message: "Thank you",
size: 'medium'
});
// document.getElementById('<%=hdField.ClientID %>').value = "true";
} else {
bootbox.alert({
message: "Please go back to your saved location\n and send the renewal email.",
size:'small'
});
// document.getElementById('<%= hdField.ClientID %>').value = "false";
PageMethods.testCSharp();
function onSuccess(result) {
alert(result);
}
function onFailure(result) {
alert("Failed!");
}
}
console.log('This was logged in the callback: ' + result);
}
});
}
C#
[WebMethod]
public static void testCSharp(bool result, GridView GridView1, object sender, EventArgs e)
{
bool variable = result;
string t = result.ToString();
MessageBox.Show(t);
string UniqClient = GridView1.SelectedRow.Cells[1].Text;
string UniqPolicy = GridView1.SelectedRow.Cells[3].Text;
string emailed = "No";
string query = "UPDATE [Reviewed_Renewal_Policy] SET [Emailed] = #emailed where where ([UniqClient] = #UniqClient) AND ([UniqPolicy] = #UniqPolicy)";
using (SqlConnection conn = new SqlConnection("Data Source=GTU-BDE01;Initial Catalog=GTU_Apps;Integrated Security=True"))
{
using (SqlCommand comm = new SqlCommand(query, conn))
{
comm.Parameters.AddWithValue("#UniqClient", UniqClient);
comm.Parameters.AddWithValue("#UniqPolicy", UniqPolicy);
comm.Parameters.AddWithValue("#emailed", emailed);
conn.Open();
comm.ExecuteNonQuery();
conn.Close();
}
}
return;
}
The issue is the PageMethods call to this method never works. I was receiving and error that PageMethods wasn't setup correctly, but changing the method to public static void fixed it. However, it executes nothing in the method itself.
I had the SQL query commented out and used the MessageBox.Show as a test, but it doesn't work. Does anyone have any idea why or how I can have this code executed based off what option is chosen in the JavaScript? Thanks for the help
You need to use an Ajax call in order send a value to your C# function.
$.ajax({
data: formData,
method: "Post",
url: url,
processData: false,
contentType: false,
success: function (d) {
SuccessMessage(successMsg);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
ErrorMessage(errorMsg);
}
});
Something similar to this. URL will be the path to your c# method.
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 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.
I have a project in MVC4 with C#. In this project, one of my controllers has a method to be called by an Ajax function:
[HttpPost]
public string EditPackage(int id, string newPkgName)
{
try{
//do logic here
return "OK";
}catch(Exception exc){
return "An error occurred, please try later! " + exc.Message;
}
}
This method is called by the following Ajax functions, using jQuery:
$.ajax({
url: $(this).data('url'),
type: 'POST',
contentType: 'application/json; charset=utf-8',
traditional: true,
data: JSON.stringify({ id: id, newPkgName: newPkgName}),
success: function () {
location.reload(true);
successNotification("Package edited successfuly!");
},
error: function (message) {
errorNotification(message);
}
});
The problem with this code, is that even if the server returns the return "An error occurred, please try later! " + exc.Message; message in the catch, the success function is the one always called.
In order words, I never run the error function no matter what I do.
To fix this I checked the official documentation:
http://api.jquery.com/jQuery.ajax/
However, since I am failry new to this I can't understand any of the parameters, nor how to use them effectively.
How can I create a good error message with all the possible information using Ajax, jQuery and my controller?
The error part of the $.ajax call only fires if the returned status code is anything other than 200 OK. In your case you are returning a plaintext response which will therefore be 200. You can change this behaviour like this:
try {
// do logic here
return "OK";
}
catch (Exception exc) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Bad Request");
}
error: function (jqXHR, textStatus, errorThrown) {
errorNotification(textStatus);
}
You can change the HttpStatusCode to whatever suits your need.
Alternatively, you can keep the 200 response and return JSON with a flag to indicate whether or not the request was successful:
[HttpPost]
public ActionResult EditPackage(int id, string newPkgName)
{
try {
//do logic here
return Json(new { Success = true, Message = "OK"});
}
catch (Exception exc) {
return Json(new { Success = false, Message = "An error occurred, please try later! " + exc.Message });
}
}
Then you can remove the error handler, and check the state of the flag in your success handler:
success: function(response) {
if (response.Success) {
location.reload(true);
successNotification("Package edited successfuly!");
}
else {
errorNotification(response.Message);
}
},
I do the following, it might not be the best approach but it works for what I try to do.
[HttpPost]
public ActionResult EditPackage(int id, string newPkgName)
{
try{
//do logic here
return Json(new {Success = true, Message = "OK"});
}catch(Exception exc){
return Json(new {Success = false, Message = "An error occurred, please try later! " + exc.Message});
}
}
Then my Ajax looks as follows:
$.ajax({
url: $(this).data('url'),
type: 'POST',
contentType: 'application/json; charset=utf-8',
traditional: true,
data: JSON.stringify({ id: id, newPkgName: newPkgName}),
success: function (data) {
if(data.Success)
{
location.reload(true);
successNotification("Package edited successfuly!");
}
else
{
errorNotification(data.Message);
}
},
error: function (message) {
errorNotification(message);
}
});
I do this so that you have the standard error catching http errors from the server, but it means you can pass a success or failure back in a way that is more useful. It also means that if your update fails for a validation reason or something you can pass that message back nicely.