If I have a controller action to redirect to another action like so:
public ActionResult Index()
{
RedirectToAction("Redirected", "Auth", new { data = "test" });
}
public ActionResult Redirected(string data = "")
{
return View();
}
The URL bar will have something like "Redirected?data=test" in it, which AFAIK is the proper behavior. Is there a way I can pass a variable directly to the Redirected ActionResult without a change on the client?
I'd like to pass "test" directly to the Redirected ActionResult without the URL changing. I'm sure there's a simple way to do this, but it is escaping me.
I know I can make a static variable outside the functions that I can pass the variable to and from, but that doesn't seem like a proper solution.
You can use TempData variable.
public ActionResult Index()
{
TempData["AfterRedirectVar"] = "Something";
RedirectToAction("Redirected", "Auth", new { data = "test" });
}
public ActionResult Redirected(string data = "")
{
string tempVar = TempData["AfterRedirectVar"] as string;
return View();
}
This link could be helpful.
Yes, use TempData.
public ActionResult Index()
{
TempData["data"] = "test";
RedirectToAction("Redirected", "Auth"});
}
public ActionResult Redirected()
{
var data = TempData["data"].ToString();
return View();
}
I hope this could help you:
https://stackoverflow.com/a/11209320/7424707
In my opinion TempData isn't the most proper solution. If I were you I would look for another solution.
Otherwise, do you really need to call RedirectToAction (to call an action from another controller)? Or are your actions in the same controller for instance?
Related
I have the following Get action:
[HttpGet]
[AllowAnonymous, OnlyAnonymous]
public ActionResult VerifyVoucherCode()
{
var model = new VerifyVoucherCodeModel();
model.VoucherCode = Request.GetFirstQueryValue("token", "voucherCode");
if (!string.IsNullOrEmpty(model.VoucherCode))
{
// prepopulates the code for the user already in a form
}
return View(model);
}
And a POST action for when the user submits the form:
[HttpPost, AjaxOnly]
[AllowAnonymous, OnlyAnonymous]
[ValidateAntiForgeryToken]
public ActionResult VerifyVoucherCode(VerifyVoucherCode model)
{
return ExecuteAction(() =>
{
// do something
});
}
I want to change the logic so that if the voucher code is in the request, the form is submitted automatically for the user without them having to submit the form themselves (i.e. it takes them straight to that Post action). I've looked at lots of Stack Overflow questions and answers and it seems I cannot redirect to the Post action. I have also tried creating a second Get action which calls the Post action but that does not work either. Does anyone know the correct way to approach this problem?
Thanks
Assuming the model contains a single string for the voucher, you can do something like this:
[HttpGet]
[AllowAnonymous, OnlyAnonymous]
public ActionResult VerifyVoucherCode(string id)
{
if(string.IsNullOrEmpty(id))
{
MyModel model1 = new MyModel();
...
return View(model1);
}
//otherwise process the voucher here
...
return RedirectToAction("SuccessMsg");
}
So in the same controller I have a Login Action method like this:
public ActionResult Login()
{
LoginModel model = this.LoginManager.LoadLoginPageData();
this.ForgotPasswordMethod = model.ForgotPasswordMethod;
return View(model);
}
Notice I set a variable there: ForgotPasswordMethod
So now when there on that page if they click on a link, it call another action result in the same controller class like this:
public ActionResult ForgotPassword()
{
if (!string.IsNullOrWhiteSpace(this.ForgotPasswordMethod) && this.ForgotPasswordMethod.Trim().ToUpper() == "TASKS")
return View();
return null; //todo change later.
}
Notice I tried to read the value of ForgotPasswordMethod , but it was NULL but it is NOT null when I am in the Login() method. So what should I do?
ASP.NET MVC was designed to return back to a cleaner, more straightforward web world built on HTTP, which is stateless, meaning that there is no "memory" of what has previously occurred unless you specifically use a technique that ensures otherwise.
As a result, whatever state you set via one ActionResult will no longer be the same state that exists when another ActionResult is invoked.
How do you "fix" this? You have a variety of options, depending on what your needs are:
Render the value to the client and post the value back to your second ActionResult method.
Store the value as a header and check that header.
Store the value in a cookie and check the cookie.
Store the value in session.
Store the value in a database.
Store the value in a static dictionary.
what if you store forgotpasswordmethod in Viewbag like
public ActionResult Login()
{
LoginModel model = this.LoginManager.LoadLoginPageData();
Viewbag.ForgotPasswordMethod = model.ForgotPasswordMethod;
return View(model);
}
then in the link of your page you can pass the value from the ViewBag
<a href=#Url.Action("ForgotPassword", "Name of your Controller", new { methodName = ViewBag.ForgotPasswordMethod })>Forgot Password</a>
Change your forgotpassword to
public ActionResult ForgotPassword(string methodName)
{
if (!string.IsNullOrWhiteSpace(methodName) && methodName.Trim().ToUpper() == "TASKS")
return View();
return null; //todo change later.
}
I was looking for a way to redirect with POST and the solutions I've found suggest simply using the action's name I want and fill the params. All of this within the same controller (let's call it Home)
[HttpPost]
public ActionResult Zoro(NameOfMyModel model, string stringName)
{
//Do whatever needs to be done
return Foo("bar",123);
}
[HttpPost]
public ActionResult Foo(string Name, int Age)
{
//Code here that use the params
return View();
}
So that works great except that when you look at the url, it doesn't show /Home/Foo, it shows /Home/Zoro. Can I fix this without using RedirectToAction? If I use it, I get this: Home/Foo?Name=bar&Age=123 Which I don't want.
Instead of calling directly calling Foo() use RedirectToAction() with this overload of it.
The way you doing calls the action on server but not actually redirects, if you want the url to change you have to redirect to the action:
return RedirectToAction("Foo", new {Name = "bar", Age = 123});
UPDATE:
As in comments mention how to keep the data temporarily ,you can use TempData[] for it:
TempData["Name"] = bar";
TempData["Age"] = 123;
return RedirectToAction("SomeAction");
and in that action you can get it from TempData:
public ActionResult SomeAction()
{
string Name = TempData["Name"] as string;
int Age - TempData["Age"] as int;
return View();
}
NOTE:
Note that RedirectToAction() only works with actions which are HttpGet, it will not work with HttpPost actions.
I have:
public ActionResult Create(Guid appId)
{
var vm = new CreateViewModel(appId);
return View(vm);
}
[HttpPost]
public ActionResult Create(CreateViewModel vm)
{
// this does some stuff
}
Now, in the View I use this for creating the Form:
#using(Html.BeginForm())
{
}
Standard.
How ever, it produces the wrong HTML:
<form action="/SomeController/Create?appId=414FDS-45F2SF-TEF234">
This is not what I want posted back, I don't want appId what so ever. Just the Create
How do you get around this?
You can use another overload of Html.BeginForm to explicitly specify the action you want:
#using(Html.BeginForm("Create", "SomeController"))
{
}
This will not append anything to the URL by default.
In my MVC3 app, if i type in a query string value in the url and hit enter, I can get the value i typed:
localhost:34556/?db=test
My default action which will fire:
public ActionResult Index(string db)
The variable db has "test" in it.
Now, i need to submit a form and read the query string value, but when I submit the form via jQuery:
$('#btnLogOn').click(function(e) {
e.preventDefault();
document.forms[0].submit();
});
And the following is the form i'm sending:
#using (Html.BeginForm("LogIn", "Home", new { id="form1" }, FormMethod.Post))
Heres the action:
[HttpPost]
public ActionResult LogIn(LogOnModel logOnModel, string db)
{
string dbName= Request.QueryString["db"];
}
The variable dbName is null because Request.QueryString["db"] is null, so is the variable db being passed in and i dont know why. Can someone help me get a query string variable after a form is submitted? Thanks
You could have something like
Controllers:
[HttpGet]
public ActionResult LogIn(string dbName)
{
LogOnViewModel lovm = new LogOnViewModel();
//Initalize viewmodel here
Return view(lovm);
}
[HttpPost]
public ActionResult LogIn(LogOnViewModel lovm, string dbName)
{
if (ModelState.IsValid) {
//You can reference the dbName here simply by typing dbName (i.e) string test = dbName;
//Do whatever you want here. Perhaps a redirect?
}
return View(lovm);
}
ViewModel:
public class LogOnViewModel
{
//Whatever properties you have.
}
Edit: Fixed it up for your requirement.
Since you are using POST the data you are looking for is in Request.Form instead of Request.QueryString.
As #ThiefMaster♦ said, in a POST you cannot have the query string, never the less if you don't wan't to serialize your data to an specific object you can use the FormCollection Object which allows you to get all the form elements pass by post to the server
For example
[HttpPost]
public ActionResult LogIn(FormCollection formCollection)
{
string dbName= formCollection["db"];
}