Persist data across multiple controllers - javascript

I have a login form (created with Html.BeginForm()) with an email field, password field, and a "Forgot Password?" link within it. Originally, it was a submit button within the login form, and it would intercept the SignIn action. I wanted to abstract the Forgot Password functionality from the SignIn action.
In doing so, I noticed that it was set up this way in order to pass the email field value to the Forgot Password page (so the user wouldn't have to re-enter it). That was placed into TempData.
My thought was to have an AJAX call to a new controller action:
[HttpPost]
[AllowAnonymous]
public ActionResult ToForgotMyPassword(string email)
{
TempData["signInEmail"] = email;
return Json(new { redirectUrl = Url.Action("ForgotMyPassword"), TempData = TempData, email = email });
}
But my problem I've found is the TempData doesn't persist to the next action, ForgotMyPassword. On my view, I have the following JS:
$('#forgotPassword').click(function (e) {
var forgotMyPasswordUrl = $(this).attr('href');
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("ToForgotMyPassword")',
data: { email: $('#Email').val() },
dataType: "json",
beforeSend: function (xhr) {
console.log(xhr);
},
success: function (result) {
//alert('Success');
console.log(result);
window.location = result.redirectUrl;
},
error: function (result) {
alert('Error');
console.log(result);
//window.location = forgotMyPasswordUrl;
}
});
});
How would I go about persisting this TempData to the redirect page? Is the way I'm going about this just not suited for an AJAX call? Should I just make a new model and new form within the Login form?

I tried to repeat your problem. And here what I done:
Controller:
[HttpPost]
[AllowAnonymous]
public ActionResult ToForgotMyPassword(string email)
{
TempData["signInEmail"] = email;
return Json(new { redirectUrl = Url.Action("ForgotMyPassword")});
}
[HttpGet]
[AllowAnonymous]
public ActionResult ForgotMyPassword()
{
var email = TempData["signInEmail"];
return View("Index", email);
}
View:
#model string
<html>
<head>
<title>#Model</title>
</head>
<body>
<div>
<input id="email" value="test#test.com"/>
<button id="forgotPassword">forgotPassword</button>
</div>
</body>
</html>
<script>
$('#forgotPassword').click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: '#Url.Action("ToForgotMyPassword")',
data: { email: $('#email').val() },
dataType: "json",
beforeSend: function (xhr) {
console.log(xhr);
},
success: function (result) {
console.log(result);
window.location = result.redirectUrl;
},
error: function (result) {
alert('Error');
console.log(result);
}
});
});
</script>
And all this stuff works fine, so i checked two theories:
1) If you try to send TempData ("TempData = TempData" in next code fragment)
Json(new { redirectUrl = Url.Action("ForgotMyPassword"), TempData = TempData, email = email });
TempData will be cleared, it will not have any element in it's collection
2) if you input id="email" and in script you use $("#Email").val() - you will got nothing. name should be equals
I hope it helps.

Related

Passing parameters in Ajax post back in MVC

I am trying to pass ID parameter from a view to a controller on a click delete link available on a selected row.
Simplified View Layout
#using (Html.BeginForm("#", "Schedule", FormMethod.Post, htmlAttributes: new { #class = "floating-labels" }))
{
#Html.AntiForgeryToken()
Delete
}
JavaScript
<script type="text/javascript">
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
$.ajax({
type: "POST",
url: '#Url.Action("Delete", "Schedule", new { id = "id" })',
contentType: "application/json",
data: { id },
async: true,
cache: false,
success: function (result) { success(result); }
});
}
return false;
}
function success(result) {
$("#ScheduleList").html(result);
}
</script>
Controller
namespace Controllers
{
public class ScheduleController
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
//do stuff
}
}
}
But on the click of a delete link I get below error and code does not hit controller action.
I am not able to figure out what mistake I am making...
Here is my locally tested implementation that is working.
ScheduleController class:
public class ScheduleController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Delete(int id)
{
return Ok(id);
}
}
Page that sends the post request:
#Html.AntiForgeryToken()
Delete
<div id="ScheduleList"></div>
<script>
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
var uri = '/Schedule/Delete?id=' + id;
var tokenElement = document.getElementsByName('__RequestVerificationToken')[0];
var data = {
__RequestVerificationToken: tokenElement.value
}
$.ajax({
type: "POST",
url: uri,
data: data,
success: function (result) {
success(result);
}
});
}
return false;
}
function success(result) {
$("#ScheduleList").html(result);
}
</script>
The page does nothing but render the html, and the javascript handles the actual Ajax post. What I believe you were missing is the Validation token in your request.
It is because you are not actullay posting the form pass it correctly and add _token in the ajax data list and value for that token will come from #Html.AntiforgeryToken()
reading the error the request is most probably send correctly and there is an internal server error as mentioned in the 500 respond so please check the code that is inside the controller
Try this, you are accesing a javascript variable on c# code, and you cant do that.
If correct, please mark as answer.
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
var url = '#Url.Action("Delete", "Schedule")?id=' + id;
$.ajax({
type: "POST",
url: url,
contentType: "application/json",
data: { id },
async: true,
cache: false,
success: function (result) { success(result); }
});
}
return false;
}
I think none of the answers above solve the issue. First of all I would replace your target url:
url: '#Url.Action("Delete", "Schedule", new { id = "id" })',
with
url: '#Url.Action("Delete", "Schedule", new { id = actualIdVariable })',
(replace "id" with the actual id variable from the model you're passing to the view).
Note how your browser response is telling you that the url you're posting to is Schedule/Delete/id. That said, I'm not sure you even need the routeValues in this case (the new { id = ...} parameter). this is a POST action, and action parameters wouldn't come from route unless specified by by attribute routing (i.e. [Route("~/Schedule/Delete/{id}")] attribute on your action).
I think your post action is failing because it is trying to parse the "id" string as an int.
Second, I would change the data property of the ajax call and include the anti forgery token. Just because the anchor element you're binding the click event to, is inside the form with #Html.AntiforgeryToken() doesn't mean the generated token will be posted in the ajax request. You're not actually submitting/posting the form, you're just clicking a button.
it should be something like
data: {
'id': id,
'__RequestVerificationToken': $('[name="__RequestVerificationToken"]').val()
}
try this, it solve the error on routing (different url Action) and the parameter on the controller:
JavaScript
<script type="text/javascript">
function DeleteSchedule(id) {
if (confirm('Are you sure you want to delete this Schedule?')) {
$.ajax({
type: "POST",
url: '#Url.Action("Delete", "Schedule")',
data: "id=" + id ,
async: true,
cache: false,
success: function (result) { success(result); }
});
}
return false;
}
function success(result) {
$("#ScheduleList").html(result);
}
</script>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(string id)
{
//do stuff
}
Nicola.

Asp.net controller recieving null

My ASP.net controller is receiving null instead of passed in parameters :(
Js function:
function SendFormToController() {
var username = document.getElementById("UsernameField").value;
var email = document.getElementById("EmailField").value;
var password = document.getElementById("PasswordField").value;
var SendJson = {
Username: username,
Email: email,
Password: password
};
console.log(JSON.stringify(SendJson));
$.ajax({
type: "POST",
data: JSON.stringify(SendJson),
url: "Register/Register",
contentType: "application/json"
});
}
Data is present when I console log it. But in the controller, I get - https://prnt.sc/u2mpa6
And it is for every field here
First; Did you add the [HttpPost] attribute on top of your controller method?
Second; If you submit it in 'querystring' format: Username=xx&Password=yy&... and use (HttpGet). Does that work?
If you need to do a POST (and not want to use GET) you can create an object with all your current arguments and use the [FromBody] attribute:
[Route("Register")]
[HttpPost]
public ResultData Register([FromBody] RegisterRequest data) {
//Your logic...
}
And client (JavaScript) side:
let url = 'http://...';
$.post(url, { Username: name, Password: pass, What: ever }, function (result) {
//Do some nice stuff
})
.fail(function (error) {
//Oh no! Show error.statusText
});

json function not call via using jquery ajax mvc

I am using model pop-up and I want to call controller but json function not calling. when I use a breakpoint in jquery data fill in the textbox but function not call. kindly tell me where I am wrong.
first, I declare a variable then store password textbox value then pass password parameter then I click save and using breakpoint message show undefine and I remove previous code then I use this code its not calling function.
Javascript
<script>
function mSavePassword() {
$.ajax({
url: "#Url.Action("ChangePassword")",
type: "GET",
contentType: "application/json;charset=UTF-8",
data: {
Password: $('#txtcurrentpassword').val(),
NewPassword: $('#txtpassword').val(),
ConfirmPassword: $('#txtConformPassword').val()
},
dataType: "json",
success: function (Record) {
alert("Record Inserted Successfully");
},
});
}
</script>
JSON FUNCTION
public JsonResult ChangePassword(User U)
{
try
{
con = new SqlConnection(constring);
con.Open();
cmd = new SqlCommand("select User_password from BriskSecurity.dbo.Users where User_Id=" + Session["AgentID"] + "", con);
string mPwd = Convert.ToString(cmd.ExecuteScalar());
if (Cryptographer.Encrypt(U.Password.Trim()) != mPwd.Trim())
{
TempData["old"] = "Incorrect Password";
return Json(TempData["old"], JsonRequestBehavior.AllowGet);
}
if (U.NewPassword.Trim() != U.ConfirmPassword.Trim())
{
TempData["Wrong"] = "Your New Password and Confirm Password do not match";
return Json(TempData["Wrong"], JsonRequestBehavior.AllowGet);
}
U.ConfirmPassword = Cryptographer.Encrypt(U.ConfirmPassword);
cmd = new SqlCommand("update BriskSecurity.dbo.Users set User_password='" + U.ConfirmPassword + "' where User_ID=" + Session["AgentID"] + "", con);
cmd.ExecuteNonQuery();
con.Close();
TempData["PSuccess"] = "Your password has been changed successfully";
}
catch (Exception)
{
TempData["Error"] = "Password not changed due to an error Try Again";
return Json(TempData["Error"], JsonRequestBehavior.AllowGet);
throw;
}
return Json("", JsonRequestBehavior.AllowGet);
}
I would suggest way to send dynamic url to ajax javscript from C# MVC page.
I very easy to use a form like:
<form method="post" action="#Url.Action("ChangePassword")">
<input ... />
<input ..../>
<input type="submit" value="Change password" />
</form>
and with jQuery:
$("form").on("submit", function(e) {
mSavePassword($(this));
});
function mSavePassword($form) {
$.ajax({
url: $form.prop("action"),
type: $form.prop("method"),
data: {
Password: $('#txtcurrentpassword').val(),
NewPassword: $('#txtpassword').val(),
ConfirmPassword: $('#txtConformPassword').val()
},
dataType: "json",
success: function (record) {
alert("Record Inserted Successfully");
}
});
}
and do changes on server side:
[HttpPost]
public JsonResult ChangePassword(User U)
otherwise, won't work

ASP.NET MVC call Controller Action with parameter from javascript function

I have web application in ASP.NET MVC C#. I want to call Controller Action method with parameters from javascript but I get always null for parameters.
In .js I have:
$.ajax({
cache: false,
url: this.saveUrl,
type: 'post',
success: this.nextStep,
complete: this.resetLoadWaiting,
error: Checkout.ajaxFailure
});
nextStep: function (response) {
if (response.error) {
if ((typeof response.message) == 'string') {
alert(response.message);
} else {
alert(response.message.join("\n"));
}
return false;
}
if (response.redirect) {
ConfirmOrder.isSuccess = true;
location.href = response.redirect;
return;
}
if (response.success) {
ConfirmOrder.isSuccess = true;
window.location = ConfirmOrder.successUrl;
//window.location.href = #Url.Action("Completed", "Checkout", new { customerComment = "test", customerDate = "2018-12-31" });
//window.location.href = '#Html.GetUrl("Completed", "Checkout", new { customerComment = "test", customerDate = "2018-12-31" })';
}
Checkout.setStepResponse(response);
}
in RouteProvider.cs I have:
routes.MapLocalizedRoute("CheckoutCompleted",
"checkout/completed/{orderId}/{customerComment}/{customerDate}",
new { controller = "Checkout", action = "Completed", orderId = UrlParameter.Optional, customerComment = UrlParameter.Optional, customerDate = UrlParameter.Optional },
new { orderId = #"\d+", customerComment = #"\w+", customerDate = #"\w+" },
new[] { "Nop.Web.Controllers" });
And finaly in Controller I have:
public virtual ActionResult Completed(int? orderId, string customerComment, string customerDate)
{
//some code here
}
I always get parameters value null and I don't know why. I try to call this Action with parameters on several diferent way like I saw on this forum but no success.
Did you add httpPost wrapper to your controller ?
[HttpPost]
public virtual ActionResult Completed(MyClass MyClassObj )
{
//some code here
}
in your Ajax code u didn't mention your Data type And Data try This Ajax
function Save () {
try {
var req = {
DeliveryCode: value,
}
$.ajax({
url: URL,
type: 'POST',
data: req,
dataType: "json",
async: true,
success: function (result) {
resetLoadWaiting()
},
error: function (e) {
}
});
}
catch (e) {
}
}
Mistake was in url string. Correct one is
ConfirmOrder.successUrl = "http://localhost:8079/checkout/completed/?customerComment=eee&customerEstimateShippingDate=2017-11-14"
I found this solution in this answer: Routing with Multiple Parameters using ASP.NET MVC
I dont need to update RouteProvider with new parameters. It is enough to put in in Controller Action method. Other things happen automatically.

Ajax call failing to get the return message from web api service

I am making a simple ajax call to the web api service that serves an authentication routine.
My problem is the ajax call can make a request to the service but errors out once the service returns a boolean value.
WHAT I WANT:
All i want to do is check if the returned boolean is true or false. If true i want to redirect the user to another page.
Could somebody please help me out on this?
JQUERY CODE:
<script type="text/javascript">
$(document).ready(function () {
$('#submitButton').click(function () {
var name = $(userNameTextBox).val);
var pass = $(passwordTextBox).val();
if (name.length == 0 || pass.length == 0) {
alert("Please enter your credentials");
}
else {
$.ajax({
url: "http://localhost:50503/api/Authentication/Authenticate",
data: { userName: name, passWord: pass },
cache: false,
type: 'GET',
dataType: 'json',
success: function (msg) {
alert(msg);
},
error: function (msg) {
alert("Error Message: "+msg);
}
});
}//end of else
});
});
</script>
Here is my webapi service
public class AuthenticationController : ApiController
{
[HttpGet]
[Route("api/Authentication/Authenticate")]
public bool Authenticate(string userName,string passWord)
{
if (userName.ToLower().Equals("username") && passWord.ToLower().Equals("password"))
{
return true;
}
else
{
return false;
}
}
}
You can try replace your ajax call by this maybe, remove the dataType:
var request = $.ajax({
url: "http://localhost:50503/api/Authentication/Authenticate",
cache: false,
type: 'POST',
data: { userName: userName, passWord: passWord }
});
request.done(function (msg) {
//check the boolean and redirect user to another page.
if(msg) window.location.href = "http://nextpage.com";
});
i also change the method to POST. More appropriate in your case.
If all else fails, put a debugger breakpoint (e.g., via the debugger directive in your error callback to $.ajax and run your code in the browser's debugger (i.e. Chrome dev tools). Then, after the breakpoint is hit, you should be able to determine (by walking the stack) why the error callback is invoked.
My Test
I've tried to reproduce your case, and for me it doesn't fail. I've defined a test controller in the following way:
using System.Web.Http;
namespace Test
{
public class TestController : ApiController
{
[HttpGet]
public bool Authenticate(string username, string password)
{
return username == "user" && password == "pass";
}
}
}
And I make an AJAX call to it from JavaScript like so:
$.ajax({url: 'http://localhost:59900/api/test', type: 'get', dataType: 'json', cache: false, data: { userName: 'user', passWord: 'pass' }}).done(function () {console.log("Success", arguments);}).fail(function () { console.log("Error", arguments); });
The AJAX call invokes the success callback (done) with true as its result, so no issues at all.
Parser Error
It appears that jQuery can't parse the JSON sent from Web API (true). To return valid JSON, return an object of the following type from your controller:
public class Result
{
public bool Result { get;set; }
}
This should result in the following JSON being sent to your client:
{ "Result": true }
Updated controller:
namespace Test
{
public class TestController : ApiController
{
[HttpGet]
public Result Authenticate(string username, string password)
{
return new Result { Result = username == "user" && password == "pass" };
}
}
}
Try to use (worked for me, check responseJSON.Message of first parameter object):
$.post(url, jsonData).
done(function (data) {}).
fail(function (xhr, status, err) {
alert("Error " + err + ". " + xhr.responseJSON.Message);
});

Categories

Resources