MVC page to page redirection - asp.net-mvc-4

I'm new to MVC (using 4, framework 4.0) and I understand the basics but this page redirect isn't working as I expect. The application is a login/authentication which if the user successfully logs in it redirects them to the target application. That part works just fine. However the user may forget his/her login credentials, so I have a series of pages that will prompt the user for a registered email address and decoded captcha value. If that information is validated then another page prompts for a series of (up to 3) pre-determined security question answers (in the case of a password forgotten). If the security challenge question is successfully answered the user is redirected to a password change page. At any point in the process the user may click a cancel button which should redirect back to the login page and clear any state variables tracking their progress through the recovery process. The problem is I keep getting stuck on pages that even after a RedirectToAction("SomeAction", "SomeController"); I still stay on the page? The URI even changes on the browser but the page asking for email address or security question stays active. I'm using an ajax $.get() to call various actions for submit and cancel.
view is defined like this:
#using (Html.BeginForm("RecoverUserCredentialsByModel", "Account", FormMethod.Get, new { id = "form1" }))
{
<!--... three input controls and a submit and cancel button-->
<p>
<button id="btnSubmit" onclick="return CheckUserEmail()">Submit</button>
<button id="btnCancel" onclick="return CancelRecovery()">Cancel</button>
</p>
}
<script type="text/javascript">
function CheckUserEmail() {
var emailAddress = document.getElementById("EmailAddress").value;
var pictogramHref = document.getElementById("pictogramHref").src;
var pictogramAnswer = document.getElementById("Pictogram").value;
if (emailAddress != null) {
var url = "/Account/ValidateEmail";
$.get(url, { "emailAddress": emailAddress, "pictogramHref": pictogramHref, "pictogramTranslation": pictogramAnswer }, null);
return true;
}
}
</script>
<script type="text/javascript">
function CancelRecovery() {
var url = "/AuthenticationModule/Account/CancelRecovery";
$.get(url, {}, null);
return true;
}
</script>
Codebehind redirections look like:
/// <summary>
/// Global cancel recovery, clears the stateful session object and redirects back to login view
/// </summary>
/// <returns>ActionResult</returns>
[AllowAnonymous]
public ActionResult CancelRecovery()
{
LoginModel statefulLoginModel = null;
try
{
// Reset everything active and redirect to login view
statefulLoginModel = new LoginModel();
Session["LoginModel"] = statefulLoginModel;
return Redirector(statefulLoginModel);
}
catch (Exception ex)
{
// Log the error and Reset everything active and redirect to login view
FileLogger.Log(ex);
statefulLoginModel = new LoginModel();
Session["LoginModel"] = statefulLoginModel;
return Redirector(statefulLoginModel);
}
}
[AllowAnonymous]
public ActionResult Redirector(LoginModel model)
{
... some code
Session["LoginModel"] = statefulLoginModel;
if (loginState == 0)
{
RedirectToAction("LogOn");
}
}
When it hits the RedirectToAction("LogOn"); the view "RecoverUserInfo" stays active on the browser and no redirection occurs?
What am I doing wrong?

Try this..........
Proper Syntax is return RedirectToAction("ActionName","ControllerName");
In this case if Logon Action is written on the same Controller Then use following Code..
return RedirectToAction("LogOn");
or it is written on another controller then just replace your Action Name and Controller Name in the following code.
return RedirectToAction("ActionName","ControllerName");

Related

Stripe Dotnet Checkout Session Creation for SCA

I feel like I'm missing the obvious here. I have implemented the Checkout process using the older process of
#using (Html.BeginForm("Submit", "Basket", FormMethod.Post))
{
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"></script>
}
//C# Controller Action
[HttpPost]
public ActionResult Submit(string shoppingCartId, string stripeToken)
{
ChargeCreateOptions chargeOptions = new ChargeCreateOptions
{
Amount = 100* 100,
Currency = "GBP",
Description = "Some stuff",
ReceiptEmail = "yo#dawg.com"
};
//3)Make the charge
var chargeService = new ChargeService("mySecretKey);
var stripeCharge = chargeService.Create(chargeOptions, null);
stripeResponse = stripeCharge.StripeResponse;
return true;
}
The process above works by showing a blue Pay button and when you click it, it invokes a modal pop-up that accepts the Credit Card Details and when Submitted, hands-off to my action and makes the payment.
For the newer SCA process, it talks about creating a session and invoking the payment process through a button click that calls the following:
stripe.redirectToCheckout({
sessionId: '{{CHECKOUT_SESSION_ID}}'
}).then(function (result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
});
I can't see how I create this {{CHECKOUT_SESSION_ID}} with the Stripe Dotnet latest version 25.7.00. Is this something that doesn't exist yet, or how does one create it?

MVC 4 website back press return the same form with old values

I am new in MVC 4 web development and i am creating a control panel. I have developed a Add user page and submit information in database successfully.
But after submit when i press back button it will show previous form.
i am using redirection the page to same page after submit form.
here is the code to redirect
public ActionResult AdminPanel(RegisterUserModel user)
{
if (ModelState.IsValid) // Check the model state for any validation errors
{
if (user.AddUserToDB(user.username, user.password, user.fullName,user.contactNo,user.COAId)) // Calls the Login class checkUser() for existence of the user in the database.
{
TempData["SuccessMessage"] = "User Added Sucessfully!";
ModelState.Clear();
return Redirect("AdminPanel");
}
else
{
ViewBag.SuccessMessage = "User Not Added";
return View();
}
}
SelectList clientsList = GetClinetList();
ViewBag.clientsList = clientsList;
return View(); // Return the same view with validation errors.
}
I have tried many examples but issue not resolved yet so kindly give my suggesstions
If you don't want the user to be able to see the previous content when clicking back, then you must indicate that content should not be cached by the browser and must revalidate with the origin server
A summary of this behaviour is here - http://blog.55minutes.com/2011/10/how-to-defeat-the-browser-back-button-cache/
You could create a nocache attribute, like this one - https://stackoverflow.com/a/10011896/1538039, and apply it to your controller methods.

Laravel route with variable in the url

I am trying to implement the password reset logic. The user gets the link to reset the password in the email. The url looks like
http://example.com/reset/resetcode
I have the route defined for it:
Route::get('reset/{resetcode}', function(){
return View::make('users.reset_password');
});
The form is rendered in the view to submit the email, new password etc. For the post of the form I have route defined as:
Route::post('reset/{resetcode}', array( 'as' => 'reset', 'uses' => 'UserController#passwordReset'));
I grab the resetcode from post route inside the passwordReset controller below
public function passwordReset($resetcode)
{
$validation = Validator::make(Input::all(), UserModel::$rulesPasswordReset);
if ($validation->passes())
{
try
{
// Find the user using the user email address
$user = Sentry::findUserByLogin(Input::get('email'));
// Check if the reset password code is valid
if ($user->checkResetPasswordCode($resetcode))
{
// Attempt to reset the user password
if ($user->attemptResetPassword($resetcode, 'new_password'))
{
// Password reset passed
}
else
{
// Password reset failed
}
}
else
{
// The provided password reset code is Invalid
}
}
catch (Cartalyst\Sentry\Users\UserNotFoundException $e)
{
echo 'User was not found.';
}
}
else return Redirect::route('reset')->withInput()
->withErrors($validation)
->with('title', 'resetrequestfailure')
->with('message', 'Seems like you made some errors.');
}
The problem I am having is when I do Redirect::route after the validation fails. I am getting the resetcode from the route defined for post. When validation fails, the redirect route messes up and I cannot get the resetcode the second time. The supposed url of format
http://example.com/reset/8f1Z7wA4uVt7VemBpGSfaoI9mcjdEwtK8elCnQOb
becomes
http://bcnet.org/reset/%7Bcode%7D
It has to do with /{resetcode} part of the route and this is variable, so how can I get the correct resetcode even after the validation fails meaning that the url remains intact. Or how can I fix it to the appropriate Redirect::route after the validation failure.
You need to include the $resetcode on your return
else return Redirect::route('reset', $resetcode)->withInput()
->withErrors($validation)

How to Set value for Hidden field in Razr MVC

In my application I need to pass some values from one page(page A to Page B) to another page.
For this I am using Session variables(I cannot use Tempdata as it doesn't work on loadbalancing).
In Page A I am setting the Session Variable.
In Page B I need to retrieve the above Session variable.
For this I am using a Hidden field in Page B.
I dont know how to set the Session Variable to Hidden Field in Page B.
Page A
[HttpPost]
public JsonResult GetFileName(string updatedfileName, string orgfileName)
{
Session["OrgFileName"] = orgfileName;
Session["UpdatedFileName"] = updatedfileName;
var result = myService.getFile(updatedfileName, orgfileName);
return Json(result, JsonRequestBehavior.AllowGet);
}
Page B
<div style="display:none" >
<input type="hidden" value="" id="hdnfilename" />
</div>
In the controller of "Page B", set a ViewBag.MyValueto your session variable and apply it to the hidden's value.
Controller
ViewBag.MyValue = Session["MYVALUE"];
View
<input type="hidden" value="#ViewBag.MyValue" id="hdnfilename" />
If you need to get a session variable from JavaScript, you will need to develop an action that will return the session variable and consume it with JavaScript/jQuery, like this:
// Controller code
[HttpGet]
public JsonResult GetSessionVarValue(string key)
{
return Json(new { key = key, value = Session[key] }, JsonRequestBehavior.AllowGet);
}
// JavaScript code
var mySessionValue;
$.getJSON("/GetSessionVarValue", "MYKEY", function(data) {
mySessionValue = data.value;
});
You may take care with Session variables in load balance, too. The best way to secure store session variables is changing the state of session mode configuration to StateServer. http://msdn.microsoft.com/en-us/library/ms178586.aspx

Allow Administrators to impersonate users using an iframe

I have an MVC project with three roles: Users, Account Managers, and Administrators.
Administrators have their own MVC Area where they have full control over Users and Account Managers. I'm trying to implement functionality to allow Administrators to view the site as any User or Account Manager.
In the Admin Area of the site, I have a View of a list of Users and Account Managers. The list contains a "View Site As User" button for each record.
I have never done anything like this before, but the ViewAs Controller Action is currently set up to create a Session with the selected User's information, like so:
ViewBag.SiteSession = Session["SiteSession"] = new SiteSession()
{
ID = user.ID,
AccountID = user.AccountID,
DisplayName = user.DisplayName,
IsManager = user.IsAdmin,
IsAdmin = false
};
The View relevant to this Action has the Model defined as a string, and nothing else but an iframe with the Model as the src attribute, like so:
#model string
<iframe src="#Model" >
</iframe>
What I'm trying to do is render whichever portion of the site was requested in this iframe. When an Administrator clicks "View As User," I'd like to direct to Home. The URL is generated through this call:
Url.Action("Index", "Home", new { Area = "" }));
The Area is set to nothing to avoid rendering the Admin Area's Home.
Currently, this is not working. I don't know where to even begin, minus what I already have.
I'm looking for any suggestions. All help is greatly appreciated, as this doesn't seem like an easy task.
If you don't know how to help, it would also be appreciated if you could direct this question to somebody that can.
Again, thanks in advance.
The way that I've done this in the past has been to use the concept of an an actual user and an effective user. Most display actions use the effective user to generate their content. Typically I've implemented it as "impersonation" rather than "preview" so the user is actually navigating the site as the user rather than displaying in a separate window. In this case I simply set both in the current session. Things that require admin permission (like switching to/from impersonation) obviously use the real user.
If you wanted to do preview then I'd think about using a parameter on each request to set the effective user. The code would need to understand to add this parameter to all links so that you could navigate in the iframe without messing up navigation in the original interface.
As for removing the area from the url, I think what you have (setting to the empty string) should work. If it's not working you might want to try lowercase area, Url.Action("Index", "Home", new { area = "" }). I'm pretty sure that the RouteValueDictionary that gets created under the hood uses a case insensitive key comparison, though, so it shouldn't matter.
For this task, I ended up creating a separate controller, ViewAsController, which had a controller-wide [Authorize] attribute that only allowed users with the Admin role to access its actions.
In the Start action, a Session object containing the selected User's information is created, like so:
[HttpGet]
public ActionResult Start(int id)
{
var user = db.Users
.First(u => u.ID == id);
Session["SiteSession"] = new SiteSession()
{
//Session data...
};
return PartialView("_IFrame");
}
This Action returns a Partial View that I ended up displaying in a jQuery UI modal dialog window.
Here's the code for that Partial View:
#{
ViewBag.SiteSession = (SiteSession)Session["SiteSession"];
}
<h2>Viewing Site As #ViewBag.SiteSession.DisplayName</h2>
<div>
<iframe src="#Url.Action("Index", "Home", new { Area = "" })"></iframe>
</div>
As you can see, it's extremely bare, and that's exactly what it needs to be. The <iframe> acts as a browser in a browser, allowing the Admin user full access to whichever Actions the selected User would.
For the sake of detail, here's the jQuery that creates the dialog and opens it:
$(function () {
$("#viewAsDialog").dialog({
modal: true,
autoOpen: false,
resizable: true,
draggable: true,
closeOnEscape: false,
height: $(window).height() * .9,
width: 1000,
closeText: '',
close: function () {
$.post("#Url.Action("End", "ViewAs", new { Area = "Admin" })")
.success(function (result) {
});
}
});
});
function viewAs(result) {
$("#viewAsDialog").html(result);
$("#viewAsDialog").dialog("open");
}
You can see here that the dialog is initialized on document-ready, and is not opened until the AJAX call that retrieves the Partial View is successfully completed.
Once the Admin closes the dialog, the server calls the End action in the ViewAs Controller, destroying the session:
[HttpPost]
public ActionResult End()
{
Session["SiteSession"] = null;
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK);
}