I am submitting a form of data via an Ajax call (I think?) to my controller to process. Once the row is saved, I am hoping to redirect to the original HttpGet action in my controller that initially loaded the form.
What I am finding is that the ajax call works, the controller action fires, and the data is saved to the database. However, the screen never refreshes after the View is reloaded.
I have a breakpoint on the 'return View(model)' on the action in my controller, which fires - but the screen doesn't refresh. If I use firebug and look at the html, I see the new row should display in my view. But, the screen doesn't seem to reload at all.
My Javascript:
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmitNewCard').click(function () {
var data = { cardNumber: $('.txtNewCardNumber').val(), cardHolder: $('.txtNewCardHolder').val(), expiryMonth: $('.txtNewExpiryMonth').val(), expiryYear: $('.txtNewExpiryYear').val(), active: $('.txtNewActive').val(), accountId: $('.Id').val() };
$.ajax({
url: '#Url.Action("SaveBankCard", "BankAccount")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result.Success == 'true') {
alert('Redirecting...');
window.location = '#Url.Action("EditBankAccount", "BankAccount", new {accountId = Model.Id})';
}
},
error: function () {
alert("Oh no");
}
});
});
});
</script>
The controller method called by the javascript above (Successfully):
public ActionResult SaveBankCard(string cardNumber, string cardHolder, int expiryMonth, int expiryYear, string active, int accountId)
{
var card = new AccountCardDto
{
Id = 0,
AccountId = accountId,
Active = active == "on",
CardHolderName = cardHolder,
CardNumber = cardNumber,
ExpiryDate = new DateTime(2000 + expiryYear, expiryMonth, 1)
};
int id = new BankAccountService().SaveCard(card);
return RedirectToAction("EditBankAccount", new { bankAccountId = accountId });
}
And then the Controller Action that gets called from the 'RedirectToAction' call:
[HttpGet]
[Authorize]
[OutputCache(Location = System.Web.UI.OutputCacheLocation.None)]
public ActionResult EditBankAccount(int? bankAccountId)
{
var model = new BankAccountModel();
if (bankAccountId != null)
{
....
}
return View(model);
}
That last line, 'return View(model)' does get called. If I check the 'model', I see the new row that was persisted to the database. But, as I say, the screen doesn't refresh.
Can anyone tell me why, and how I can fix/improve my situation?
Try this...your method SaveBankCard calling EditBankAccount in controller and ajax also then do one thing call it only in ajax or in controller
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmitNewCard').click(function () {
var data = { cardNumber: $('.txtNewCardNumber').val(), cardHolder: $('.txtNewCardHolder').val(), expiryMonth: $('.txtNewExpiryMonth').val(), expiryYear: $('.txtNewExpiryYear').val(), active: $('.txtNewActive').val(), accountId: $('.Id').val() };
$.ajax({
url: '#Url.Action("SaveBankCard", "BankAccount")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result != 0) **//if your method return int else check it null if your method return string**
{
alert('Redirecting...');
window.location = '#Url.Action("EditBankAccount", "BankAccount", new {bankAccountId= Model.Id})'; **//change name of parameters**
}
},
error: function () {
alert("Oh no");
}
});
});
});
</script>
Controller
public int SaveBankCard(string cardNumber, string cardHolder, int expiryMonth, int expiryYear, string active, int accountId)
{
var card = new AccountCardDto
{
Id = 0,
AccountId = accountId,
Active = active == "on",
CardHolderName = cardHolder,
CardNumber = cardNumber,
ExpiryDate = new DateTime(2000 + expiryYear, expiryMonth, 1)
};
int id = new BankAccountService().SaveCard(card);
int bankAccountId = accountId;
return bankAccountId ;
}
Related
I have a problem when I try to save some data to the database. I can see the ID and Date returning me appropriate values in the JS function... However, the parameter for the Process function inside the controller class remains null. I don't know why is that happening. There is a linq query that is also included in the Hello Model, but I didn't include it because there is no need for it.
Model:
public class Hello
{
List<string> Ids { get; set; }
List<string> Dates { get; set; }
}
Controller:
[HttpPost]
public ActionResult Process(string ids, string dates)
{
Hello model = new Hello();
if (ModelState.IsValid)
{
using (db = new DB())
{
rp = new RequestProcess();
//var c = rp.getHello(model, dates);
var c = rp.getStuff();
if (c != null)
{
foreach (var i in c)
{
if (i != null)
{
ids = i.ID;
dates = i.Date.ToString();
}
db.SaveChanges();
}
}
}
ViewBag.Message = "Success";
return View(model);
}
else
{
ViewBag.Message = "Failed";
return View(model);
}
}
View:
<td><input class="id" type="checkbox" id=#item.ID /></td>
<td>#Html.DisplayFor(x => #item.ID)</td>
<td><input class="date" id=date#item.ID type="text" value='#item.Date'/></td>
$(document).ready(function () {
var ids = "";
var dates = "";
$("#btnSubmit").bind("click", function () {
createUpdateArrays();
var url = "/Sample/Process";
$.ajax({
type: "POST",
url: url,
data: { ids: ids, dates: dates },
contentType: 'application/json; charset=utf-8',
success: function (success) {
if (success === true) {
alert("HERE WE ARE");
}
else {
alert("eror");
}
}
});
ids = "";
dates = "";
});
function createUpdateArrays() {
var i = 0;
$('input.remedy-id:checkbox').each(function () {
if ($(this).is(':checked')) {
var rid = $(this).attr("id");
$('.planned-date').each(function () {
var did = $(this).attr("id");
if (did === rid) {
var date = $(this).val();
ids += rid + ",";
dates += date + ",";
}
});
};
});
};
Any help would be appreciated!
I think you need contentType: 'application/json' in your $.ajax({});
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(list),
contentType: 'application/json'
});
Also, try adding [FromBody]Hello model in your controller action.
There are several issues in your code:
1) You're passing JSON string containing viewmodel properties, it is necessary to set contentType: 'application/json; charset=utf-8' option in AJAX callback to ensure model binder recognize it as viewmodel parameter.
2) return View() is not applicable for AJAX response, use return PartialView() instead and put html() to render response in target element.
Therefore, you should use AJAX setup as provided below:
$.ajax({
type: "POST",
url: url,
data: JSON.stringify(list),
contentType: 'application/json; charset=utf-8',
success: function (result) {
$('#targetElement').html(result);
},
error: function (xhr, status, err) {
// error handling
}
});
Controller Action
[HttpPost]
public ActionResult Process(Hello model)
{
if (ModelState.IsValid)
{
using (db = new DB())
{
// save data
}
ViewBag.Message = "Success";
return PartialView("_PartialViewName", model);
}
else
{
ViewBag.Message = "Failed";
return PartialView("_PartialViewName", model);
}
}
Remember that AJAX callback intended to update certain HTML element without reloading entire view page. If you want to reload the page with submitted results, use normal form submit instead (with Html.BeginForm()).
I know that same questions have answers, but they don't work in my project.
I have controller were i send message to employee.
id i take with ajax.
email i take from db. but getEmployeeEmail() returns me my email( it's right)
Controller name: EmployersActivity
Code don't work when i send post.
My ajax post code:
$(document).ready(function () {
$(".buttonSendEmail").click(function () {
var orderText = $(".orderData").text();
alert(orderText);
$.ajax({
type: "POST",
contentType: 'application/json; charset=utf-8',
url: "#(Url.Action("Create", "EmployersActivity"))",
data: { id: 1 },
dataType: "json",
traditional: true,
error: function (message) {
alert("error on start")
$(".contentReqGood").show();
redirect();
},
success: function (result) {
if (result.status === 1) {
alert("error")
} else {
$(".contentReqGood").show();
redirect();}})})});
asp.net mvc code:
[HttpGet]
[Authorize]
public ActionResult Create()
{
return View();
}
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult Create(int? id)
{
if (id == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var email = db.employees.Find(id);
if (email == null)
return HttpNotFound();
if (email != null)
{
if (db.SaveChanges() == 1)
{
string mailTemplate;
string title = "asdasd";
string preview = "asdasdasd";
var sr = new StreamReader(Server.MapPath("~/App_Data/Templates/" + "InfoEmail.txt"));
mailTemplate = sr.ReadToEnd();
string messageBody = string.Format(mailTemplate, title, preview);
new MailSender
{
Sender = "news#omegasoftware.eu",
Recipient = "news#omegasoftware.eu",
RecipientsBcc = getEmployeeEmail(),
Subject = title,
Body = messageBody
}.Send();}}
return View();}
You have several issues regarding current example:
1) [Authorize] attribute is unnecessary on POST method because using it in GET action method should be enough to prevent unauthorized users.
2) Since you're sending AJAX request to a POST method which includes [ValidateAntiForgeryToken] attribute, it is necessary to send the CSRF prevention token into AJAX request.
3) Remove dataType: "json", contentType: 'application/json; charset=utf-8' and traditional: true since you're sending single integer data and not using an array or JSON-formatted string.
4) AJAX callbacks are intended to stay in same page, hence return View() should be replaced with return PartialView().
Based from 4 issues above, if it's necessary to use AJAX, you should set the request and controller action like following example below:
AJAX Request
$(document).ready(function () {
$(".buttonSendEmail").click(function () {
var orderText = $(".orderData").text();
alert(orderText);
var form = $('form');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
type: "POST",
url: "#Url.Action("Create", "EmployersActivity")",
data: { id: 1, __RequestVerificationToken: token },
error: function (message) {
alert("error on start");
// other stuff
},
success: function (result) {
$(".contentReqGood").show();
// other stuff
}
});
});
});
Controller Action
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(int? id)
{
if (id == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
var email = db.employees.Find(id);
if (email == null)
return HttpNotFound();
if (email != null)
{
// do something
}
return PartialView("_PartialViewName");
}
Other than that, if you want to pass entire viewmodel content to POST action method or use redirection with RedirectToAction() after submit, then you should use normal form submit (with Html.BeginForm() helper) instead.
I have a JS function which takes a value from a textbox based on the Radio button selected.
Example: If RadioButton No is Selected, values is teken from TextBox A, else if RadioButton Yes is selected, Value is taken from TextBox B. The following script is in my view
$('#btnVolunteerSaveBtn').on('click', function() { // on click of save button
if (document.getElementById('RadioNo').checked) { //ID of radio button NO
var checking = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
if (checking == "") {
//if nothing is entered, stop from saving in DB
} else {
x = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
$.ajax({
url: '#Url.Action("DonationValue","VolunteerInfo")',
data: {
name: x
},
type: "POST"
});
}
} else {
x = $('#GetNames').val(); //ID of textbox from where the value is to be taken if RadioButton Yes is selected
$.ajax({
url: '#Url.Action("DonationValue","VolunteerInfo")',
data: {
name: x
},
type: "POST"
});
}
});
Till here it seems to work fine. Now coming to the controller, I have a function DonationValue
My Question:
How can I pass the name parameter above?
If nothing is filled in TextBox with id #Donation, how do I stop
from saving the form in the DB?
My Attempt:
I tried doing
public string DonationValue(string name = null)
{
return name; //Trying to pass this value above
}
This didn't help. It resolved the error but the passed value was always null. I also tried a couple of other things but none helped.
Edited:
[HttpPost]
public ActionResult AddVolunteer(VolunteerInfo viewModel)
{
if (!ModelState.IsValid)
{
return View("AddVolunteer", viewModel);
}
var volunteer = new VolunteerInfo()
{
Name = viewModel.Name,
BirthdayDateTime = viewModel.BirthdayDateTime,
Address = viewModel.Address,
PhoneNumber = viewModel.PhoneNumber,
EmailAddress = viewModel.EmailAddress,
OccasionsID = viewModel.OccasionsID,
DonationForWhom = _DonationValue
};
if (!string.IsNullOrEmpty(volunteer.DonationForWhom))
{
_context.VolunteerInfos.Add(volunteer);
_context.SaveChanges();
return RedirectToAction("Index", "Home");
}
return //something to save state so that user doesnt have to enter all the values again
}
[HttpPost]
public void DonationValue(string name)
{
_DonationValue = name;
}
#Daisy Shipton.
Is this a better solution?
<script>
$(function() {
$('#btnVolunteerSaveBtn').on('click', function() { // on click of save button
debugger;
if (document.getElementById('RadioNo').checked) { //ID of radio button NO
var checking = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
if (checking == "") {
//if nothing is entered, stop from saving in DB
}
else {
var x = $('#Donation').val(); //ID of textbox from where the value is to be taken if RadioButton No is selected
var jsonObject = {
"textValue": x,
"isRadioSelected": "true" // show the radio is selected
};
$.ajax({
url: '#Url.Action("AddVolunteer", "VolunteerInfo")',
data: JSON.stringify(jsonObject),
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "POST",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
}
}
else {
var jsonObject2 = {
"textValue": $('#GetNames').val(),
"isRadioSelected": "false" // show the radio is not selected
};
$.ajax({
url: '#Url.Action("AddVolunteer", "VolunteerInfo")',
data: JSON.stringify(jsonObject2),
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "POST",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
}
});
})
</script>
In my controller:
[HttpPost]
public ActionResult AddVolunteer(VolunteerInfo volunteerInfo)
{
if (volunteerInfo.isRadioSelected)
{
//something
}
else
{
//something
return View();
}
1) Client calls to DonationValue post method with name paramter
e.g. name="abc"
[HttpPost]
public string DonationValue(string name = null) // name = "abc"
{
return name; //Trying to pass this value above
}
This returned value to be stored in client side say variable retunedDonationValue
If you don't pass any name parameter then above post method does return empty string then just set retunedDonationValue = ''
2) Now you have to pass above retunedDonationValue to your post method in posted json object like
var jsonObject =
{
"Name" = "YourName",
"BirthdayDateTime" = "YourBirthdayDateTime",
"Address" = "YourAddress",
"PhoneNumber" = "YourPhoneNumber",
"EmailAddress" = "YourEmailAddress",
"OccasionsID" = "YourOccasionsID",
"DonationForWhom" = retunedDonationValue //Note here
}
3) And pass this post data to http call to AddVolunteer
$.ajax({
url: '#Url.Action("AddVolunteer", "VolunteerInfo")',
data: JSON.stringify(jsonObject),
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "POST",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
4) And your action method is look like
[HttpPost]
public ActionResult AddVolunteer(VolunteerInfo viewModel)
{
if (!ModelState.IsValid)
{
return View("AddVolunteer", viewModel);
}
var volunteer = new VolunteerInfo()
{
Name = viewModel.Name,
BirthdayDateTime = viewModel.BirthdayDateTime,
Address = viewModel.Address,
PhoneNumber = viewModel.PhoneNumber,
EmailAddress = viewModel.EmailAddress,
OccasionsID = viewModel.OccasionsID,
DonationForWhom = viewModel.DonationForWhom
};
if (!string.IsNullOrEmpty(volunteer.DonationForWhom))
{
_context.VolunteerInfos.Add(volunteer);
_context.SaveChanges();
}
return View(viewModel);
}
I have a situation where I am setting a user value and trying to reload the index page. This is only a sample page and I cannot user any kind of user controls, like ASP.NET. Each user is in the database and the role is retrieved from there. My index is this:
[HttpGet]
public ActionResult Index(long? id)
{
AdminModel admin = new AdminModel();
UserModel usermodel = new UserModel();
if (id != null)
{
admin.UserModel = usermodel;
admin.UserModel.UserId = id.ToString();
admin.UserModel = UserAndRoleRepository.GetOrStoreUserProfile(admin.UserModel.UserId);
}
else
{
admin.UserModel = usermodel;
admin.UserModel = UserAndRoleRepository.GetOrStoreUserProfile(currentUser);
}
return View(admin);
}
This works fine when first loaded. In the page I am setting values based upon the user role:
$(document).ready(function () {
debugger;
user = function () { return #Html.Raw(Json.Encode(Model)) }();
if (user.UserModel != null) {
if (user.UserModel.UserRole == 'ADMIN') {
$("#btnAdmin").show();
$("#btnTran").show();
$("#btnNew").show();
$("#btnAdjust").show();
$("#btnReports").show();
}
if (user.UserModel.UserRole == 'TRANS') {
$("#btnReports").show();
$("#btnTran").show();
}
if (user.UserModel.UserRole == 'REPORTS') {
$("#btnReports").show();
}
}
});
The AJAX call is this:
$.ajax({
type: 'POST',
dataType: 'json',
url: '#Url.Action("SetUser")',
data: { userid: ui.item.value },
success: function (data) {
if (data == null) {
}
else {
}
},
error: function (xhr) {
//var err = xhr.responseText;
//alert('error');
}
});
And the SetUser action:
[HttpPost]
public ActionResult SetUser(string userid)
{
return RedirectToAction("Index", new { id = Convert.ToInt64(userid) });
}
This works fine in that the Index method is fired with the chosen ID, but the page does not reload to be able to set the buttons. Any ideas?
It won't redirect because you're returning an action via an ajax call. The best thing to do here would be to return the userid as JSON, then do the redirect.
So the ajax success function would be:
success: function (data) {
if (data != null && data.UserID != null) {
location.href = '#(Url.Action("SetUser"))?userid=' + data.UserID;
}
else {
location.reload(); //something went wrong?
}
},
});
And your action would be:
[HttpPost]
public JsonResult SetUser(string userid)
{
return Json(new { UserID = Convert.ToInt64(userid) });
}
Do you need to make Ajax POST call? If not you can replace that code with
window.location.href = '#Url.Action("Index")' + '/' + ui.item.value
or
window.location.href = '#Url.Action("Index")' + '?id=' + ui.item.value
depending on your route mapping.
I have an MVC4 application, and on the layout (master page for the oldies), I have some javascript:
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmit').on('click', function () {
var data = { username: $('.txtUsername').val(), password: $('.txtPassword').val(), rememberMe: $('.cbRemember').val() };
$.ajax({
url: '#Url.Action("LoginUser", "User")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result.Success == 'true') {
window.location = '#Url.Action("Index", "Home")';
} else {
alert(result.Message);
}
},
error: function () {
alert("Error in input");
}
});
});
});
</script>
This simply logs in a user.
This is working fine.
However, on another screen I now have some new javascript, which does similar function, by taking data from a form, and passing it to a controller to handle.
<script type="text/javascript">
$(document).ready(function () {
$('.btnSubmitNewCard').on('click', function () {
var data = { cardNumber: $('.txtNewCardNumber').val(), cardHolder: $('.txtNewCardHolder').val(), expiryMonth: $('.txtNewExpiryMonth').val(), expiryYear: $('.txtNewExpiryYear').val(), active: $('.txtNewActive').val(), accountId: $('.Id').val() };
$.ajax({
url: '#Url.Action("SaveBankCard", "BankAccount")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(data),
cache: false,
async: true,
success: function (result) {
console.log(result.toString());
if (result.Success == 'true') {
// window.location = '#Url.Action("Index", "Home")';
} else {
alert(result.Message);
}
},
error: function () {
alert("Oh no");
}
});
});
});
</script>
When I click the save button that this code is linked to, the code fires, the controller method goes well, the data is stored, but then, when I refresh the screen, I get an 'Undefinied' error coming from the LOGIN script above. It seems to fire when the page is reloaded. I am unsure why it's firing. It should just load, ready to fire, but it seems to be called, and fails.
The controller that it calls is this:
public ActionResult SaveBankCard(string cardNumber, string cardHolder, int expiryMonth, int expiryYear, string active, int accountId)
{
var card = new AccountCardDto
{
Id = 0,
AccountId = accountId,
Active = active == "on",
CardHolderName = cardHolder,
CardNumber = cardNumber,
ExpiryDate = new DateTime(expiryYear, expiryMonth, 1)
};
int id = new BankAccountService().SaveCard(card);
return RedirectToAction("EditBankAccount", new { bankAccountId = accountId });
}
The problem happens on the RedirectToAction... when that view reloads, which includes the Layout, the Layout javascript fires.
EDIT: I now see that it's the btnSubmitNewCard javascript that is fired twice. Once when the click event happens (expected), and then again when the postback happens. Why is the second event happening?
Check with this: -
$('.btnSubmitNewCard').click(function () {...});
You are getting Undefined in the line that checks status:
if (result.Success == 'true') {
Because result contains string with html response of the view for the EditBankAccount action and does not have "Success" property.
You can put breakepoint in debugger and see. You can use debugger; statement as breakpoint