ReturnUrl is always null in MVC - c#

I have a return url send after a user logs in:
e.g.
/Account/SignIn?ReturnUrl=%2fToDoItems%2fCreate
However, the value in the controller isn't binding.
[HttpPost]
[ActionName("SignIn")]
public ActionResult SignInConfirmation(UserCredentialsModel model, string returnUrl)
{
if (ModelState.IsValid)
Also, the Request.QueryString is empty (bar the Length).
How do I bind the query string params to the controller?
As per below, I've tried capitalising the parameter name:
public ActionResult SignInConfirmation(UserCredentialsModel model, [Bind(Include = "ReturnUrl")] string ReturnUrl)

You want to retrieve ReturnUrl from HttpGet method, and send it back on postback.
View
#using (Html.BeginForm("SignInConfirmation", "YOUR_CONTROLLER",
new { ReturnUrl = ViewBag.ReturnUrl },
FormMethod.Post, new { role = "form" }))
{
....
}
Controller
public ActionResult SignInConfirmation(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
[HttpPost]
public ActionResult SignInConfirmation(UserCredentialsModel model, string returnUrl)
{
}

Related

(Html.DropdownList) Value cannot be null. Parameter name: items

I have a Login View Page with 2 partial views _LoginPartial and _RegisterPartial. And in _RegisterPartial I have dropdownlist that contains the roles.
#Html.DropDownListFor(m => m.CompanyProfile, new SelectList(ViewBag.CompanyProfiles, "AccountId", "AccountName"), "Select", new { #class = "form-control" })
I'm initializing this dropdownlist in the GET Method as
//
// GET: /Account/Login
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.CompanyProfiles = util.GetCompanyProfiles();
ViewBag.ReturnUrl = returnUrl;
return View();
}
and my code for getting the list from database is
public List<abo_AccountType> GetCompanyProfiles()
{
List<abo_AccountType> companyProfiles = new List<abo_AccountType>();
companyProfiles = db.GetAccountTypes().ToList();
return companyProfiles;
}
The list is initialized when we open the Login Page and I know that I need to initialize the dropdownlist again in the POST method, so I'm doing that just like I did it in the GET Method
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterViewModel model)
{
ViewBag.CompanyProfiles = util.GetCompanyProfiles();
if (ModelState.IsValid)
{
ViewBag.CompanyProfiles = util.GetCompanyProfiles();
string[] errors = util.CheckDuplicateAccount(model);
if (errors == null)
{
long currentUser = Convert.ToInt64(System.Web.HttpContext.Current.User.Identity.GetUserId());
util.CreateNewAccount(model, currentUser);
}
else
{
AddErrors(errors);
}
}
return RedirectToAction("Login");
}
Even though I'm initializing the dropdown again I still get the error that Value cannot be null. Parameter name: items.
I've searched almost all the answers on SO and they all say that I need to initialize the dropdown again, which I'm doing, so why am I still getting this error.
You should generate "GET" method for Register and set CompanyProfiles in there.
[HttpGet]
[AllowAnonymous]
public ActionResult Register()
{
ViewBag.CompanyProfiles = util.GetCompanyProfiles();
return View();
}
Create another model that having both the properties of that two models and pass it in your post action.
[HttpGet]
[AllowAnonymous]
public ActionResult Register(combinedModel model)
{
ViewBag.CompanyProfiles = util.GetCompanyProfiles();
return View(model);
}

Redirect back with message after file upload MVC 4 c#

I've working on MVC 4 application and want to redirect back with message to call action view:
Action that called : Upload
Current view : Index
public class HospitalController: Controller {
public ActionResult Index()
{
return View(Model);
}
[HttpPost]
public ActionResult Index(Model model)
{
return View(ohosDetailFinal);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//Here i want to pass messge after file upload and redirect to index view with message
// return View(); not working
}
}
#using (Html.BeginForm("Upload", "Hospital", null, FormMethod.Post, new { enctype = "multipart/form-data", #class = "" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<input type="file" id="dataFile" name="upload" class="hidden" />
}
Thanks !
Follow the PRG pattern. After successful processing, redirect the user to another GET action.
You can return a RedirectResult using RedirectToAction method. This will return a 304 response to the browser with the new url in the location header and the browser will make a new GET request to that url.
[HttpPost]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//to do : Upload
return RedirectToAction("Index","Hospital",new { msg="success"});
}
Now in the Index action, you may add this new parameter msg and check the value of this and show appropriate message. The redirect request will have a querystring with key msg (Ex :/Hospital/Index?msg=success)
public ActionResult Index(string msg="")
{
//to do : check value of msg and show message to user
ViewBag.Msg = msg=="success"?"Uploaded successfully":"";
return View();
}
and in the view
<p>#ViewBag.Msg</p>
If you do not prefer the querystring in the url, you may consider using TempData. But tempdata is available only for the next request.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//Here i want to pass messge after file upload and redirect to index view with message
return Index();//or with model index
}
Try the below code, Hope It helps.!
View
#using (Html.BeginForm("Upload", "Hospital", null, FormMethod.Post, new { enctype = "multipart/form-data", #class = "" }))
{
if (TempData["Info"] != null)
{
#Html.Raw(TempData["Info"])
}
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<input type="file" id="dataFile" name="upload" class="hidden" />
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(HttpPostedFileBase upload,FormCollection form)
{
//Here i want to pass messge after file upload and redirect to index view with message
TempData["Info"]="File Uploaded Successfully!";
return RedirectToAction("Index");
}

Pass Value from Controller to View by ViewBag

So I have a controller and I can seem to understand how to pass a parameter to my ActionResult method.
routes.MapRoute(
name: "MyRoute",
url: "{controller}/{name}/{id}",
defaults: new { controller = "Project", name = "Search", id = UrlParameter.Optional }
);
This is my route. Now in my controller i've created a method
[HttpGet]
public ActionResult Search()
{
return View();
}
[HttpPost]
public ActionResult Search(int Id)
{
ViewBag.iD = Id;
return View();
}
And in my view
<body>
<div>
ASDF + #ViewBag.iD
</div>
</body>
How can I pass a value to my iD parameter from Search Action? It seems whatever I call
http://localhost:52992/Project/Search/id=2
or http://localhost:52992/Project/Search/1
Both method go into the Search() method, none goes to Search(int iD).
What Am I missing?
A link in your view (or a form with FormMethod.Get or entering a url in the address bar) makes a GET call, not a POST, so your method should be
[HttpGet]
public ActionResult Search(int ID)
{
// do something based on the value of ID
ViewBag.iD = ID;
return View();
}
and delete the [HttpPost] method.
You have to pass value from the HttpGet 'SearchAction' method. if you pass from it, then only the value will be shown in the view
[HttpGet]
public ActionResult Search()
{
ViewBag.iD = your Id value here;
return View();
}
on intial load the get method will be called, on submission only the 'post' method will be call.
hope this helps.
On your view
<a href='#Url.Action("ActionName", "ControllerName", new { id= 10})'>...</a>
OR
#{
int id = 10
}
...
On Your Action
Public ActionResult Search(int id)
{
Viewbag.Id = id;
return view();
}
Action is by default on [HTTPGET] you wont have to mention it

How to pass values from One controller to another Controller in ASP.Net MVC3

Hello In my project I have to pass a welcome message with username to the Index Page
Its a MVC3 ASP.Net Razor project
There are two controllers are there; One is Login Controller and the second one is Home Controller. From Login Controller, I have to pass UserName of the Login Person to the view Page.
Login Controller redirect to Another controller called Home Controller .From there I have to pass that value to the view page. That's my issue. I have tried with single controller to view, its working.
I cant use the single controller because Login Controller uses Login Page and Home Controller uses Home Page. Both are separate views.
I have tried Like this, but its not working. Can you suggest a good Method to follow?
Login Controller
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(LoginModel model)
{
if (ModelState.IsValid)
{
if (DataAccess.DAL.UserIsValid(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, false);
return RedirectToAction("Index", "Home" );
}
else
{
ModelState.AddModelError("", "Invalid Username or Password");
}
}
return View();
}
Home Controller
public ActionResult Index()
{
return View();
}
You can try with Session, like
Session["username"] = username;
and for recover in the other controller use
var username = (string)Session["username"]
or in your redirect try with
return RedirectToAction("Index", "Nome", new{ username: username})
but the action of your controller must have as argument the (string username) like
public ActionResult Index(string username)
{
return View();
}
You could retrieve the currently authenticated username from the User instance:
[Authorize]
public ActionResult Index()
{
string username = User.Identity.Name;
...
}
Change the Index() method of Home Controller to this:
[HttpPost]
public ActionResult Index(string username)
{
ViewBag.user=username;
return View();
}
Modify the Login Controller :
if (DataAccess.DAL.UserIsValid(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, false);
return RedirectToAction("Index", "Home",new { username = model.Username } );
//sending the parameter 'username'value to Index of Home Controller
}
Go to the View Page of the Index method of Home Controller and add the following:
<p>User is: #ViewBag.user</p>
And you're done. :)
Use TempData. Its data is available in the next request also.
// after login
TempData["message"] = "whatever";
// home/index
var message = TempData["message"] as string;

MVC passing variables within a controller

Not sure if I am following MVC conventions but I have some variables passed from one Controller A to Controller B. My objective is to have another view named 'Publish' with an ActionLink to do some processing upon clicking on it.
The redirection from Controller A:
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index", "Publish", new { accTok = facebookAccessTok, fullImgPath = fullpath });
return Json(new { Url = redirectUrl });
I now have the values for 'accTok' and 'fullImgPath' in my 'Publish' Index for Controller B which contains an ActionLink in its View to do the processing, but I am not sure how do I pass them to my 'Publish' ViewResult' method to do it:
namespace SF.Controllers
{
public class PublishController : Controller
{
public ViewResult Index(string accTok, string fullImgPath)
{
return View();
}
// This ViewResult requires the values 'accTok' and 'fullImgPath'
public ViewResult Publish()
{
// I need the values 'accTok' and 'fullImgPath'
SomeProcessing();
return View();
}
public SomeProcessing(string accessToken, string fullImagePath)
{
//Implementation
}
}
}
Index View:
#{
ViewBag.Title = "Index";
}
<h2>Publish</h2>
<br/><br/>
#Html.ActionLink("Save Image", "Publish")
I would suggest doing this
public ViewResult Publish(string accTok, string fullImgPath)
{
SomeProcessing(accTok,fullImgPath);
return View();
}
In your controller:
public ViewResult Index(string accTok, string fullImgPath)
{
ViewModel.Acctok = accTok;
ViewModel.FullImgPath = fullImgPath;
return View();
}
public ViewResult Publish(string accTok, string fullImgPath)
{
SomeProcessing(accTok,fullImgPath);
return View();
}
In the view:
#Html.ActionLink("Save Image", "Publish","Publish",new {accTok=ViewModel.Acctok, fullImgPath=ViewModel.FullImgPath},null )
Instead of the ActionLink you could also make it a form with hidden input fields (if this method changes thing in a database/on disk, it actually should be in a post).
But anyway use a viewmodel to pass the parameters from the index action to the view, so that in turn can send them to the publish action. This is generally the way to do it with the stateless web in MVC.

Categories

Resources