Reading in RouteValues to Controller - asp.net

so I have a Url Action
Create new teacher & assign to account.
That passes in two routeValues: createAndAssign, and teacherID.
Now when I go to my Teacher/Create page, my URL is like so:
.../Teacher/Create?createAndAssign=True&teacherID=ea817321-5633-4fdc-b388-5dba2c4a728e
Which is good, I want this. Now when I POST to create my teacher, how do I grab createAndAssign and teacherID value?

You can set the Querystring value in a hidden variables in the form and render in your GET action method and accept that in your POST action method.
View rendered by your GET Action
#using (Html.BeginForm())
{
//Other form elements also
#Html.Hidden("teacher",#Request.QueryString["teacherID"] as string)
#Html.Hidden("createAndAssign",#Request.QueryString["createAndAssign"]
as string)
<input type="submit" />
}
and now have a teacher parameter and createAndAssign parameter in your HttpPost action method so that it will be available when you submit the form.
[HttpPost]
public ActionResult Create(string teacher,string createAndAssign)
{
//Save and Redirect
}
If your view is strongly typed (which is my personal preference), it is quite easy,
public ActionResult GET(string teacherID,string createdAndAssing)
{
var yourVMObject=new YourViewModel();
yourVMObject.TeacherID=teacherID;
yourVMObject.CreateAndAssign=createdAndAssing;
return View(createdAndAssing);
}
and in your strongly typed view,
#model YourViewModel
#using (Html.BeginForm())
{
//Other form elements also
#Html.HiddenFor(x=>x.TeacherID)
#Html.HiddenFor(x=>x.CreateAndAssign)
<input type="submit" />
}
And in your POST action
[HttpPost]
public ActionResult Create(YourViewModel model)
{
//look for model.TeacherID
//Save and Redirect
}

you can get the value from the query string or as params of the controller like
var x =Request.QueryString["createAndAssign"];
or
public ActionResult Create(bool createAndAssign, string teacherID){
return View();
}

Related

How should I send viewmodel to Create method in Controller?

I am trying to send data from a view to a controller Create method. But the view model parameter is getting null values when the create method is called.
In my view I want to add a item and show a list of added items.
I have tried to send data to the create method but its view model parameter is getting null values.
In the following code whenever Create method is hit the value of p.posts and p.post is null. How can I get the value of p.post and p.posts here?
Controller method
public ActionResult Create(PostsViewModel p) {}
View Model
public class PostsViewModel
{
public IEnumerable<Post> posts;
public Post post;
}
View
#model NotesWebApplication.ViewModels.PostsViewModel
...
#using (Html.BeginForm()) {
...
#Html.EditorFor(model => model.post.postText, new { htmlAttributes = new { #class = "form-control" } })
...
<input type="submit" value="Create" class="btn btn-default" />
Also in my Create method if I wanted to add Bind then which should be added
[Bind(Include="postText")]
or
[Bind(Include="post.postText")]
update
I made the following changes in PostsViewModel class
public class PostsViewModel
{
public IEnumerable<Post> posts { get; set; }
public Post post { get; set; }
}
and the Create method in the controller is changed to
[HttpPost]
public ActionResult Create([Bind(Include="post, posts")]PostsViewModel p) {}
This is what the httpget Create method looks like
// GET: Posts/Create
public ActionResult Create()
{
PostsViewModel postsViewModel = new PostsViewModel();
postsViewModel.posts = db.Posts;
postsViewModel.post = new Post();
return View(postsViewModel);
}
Now when I submit the form p.post in the controller parameter receives the desired value. But p.posts remains null. Why is this hapenning?
I guess the reason is u don`t have an instance of your post object. Try to make your viewModel something like this:
public class PostsViewModel
{
public string PostText {get;set;} // don`t forget to make it like property, not just a field
}
and then create an instance in your controller:
public ActionResult Create(PostsViewModel p)
{
Post post = new Post{ postText = p.PostText};
//and do what you want with it
}

Pass a simple ViewModel from a View to a Controller via hidden field

I am trying to pass a simple object containing only one field (a DateTime) from my view back to my controller.
I have a ViewModel that looks like this:
public class TheViewModel
{
public DateTime StartTime { get; set; }
}
I have a controller post method that looks like this
[HttpPost]
public async Task<ActionResult> StartNew(TheViewModel viewModel)
{
....
}
In my view, my model is set to TheViewModel, and I am trying to simply send the same value for the StartTime field of the ViewModel back to the Controller:
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.StartTime, new { id = "StartTimeField" })
<input type="submit" value="Start" />
}
However, the value of the StartTime field is always the default date time. I have verified that this is not the value for the time sent to the view (by looking at the page source)
What am I mnissing?
Why are you creating a new object inside the HtmlFor? Why not just #Html.HiddenFor(m=>m.StartTime) ?

how to log-off from another action

In Microsoft ASP.NET MVC 5,
how do I sign an user out from an action other than the LogOff action of the Account controller? Some years ago I would use return RedirectToAction("LogOff","Account"), but nowadays it does not work anymore since LogOff is a Post action (not GET).
public ActionResult SomeActionOfSomeController() {
// some logic
return RedirectToAction("LogOut", "Account"); //does not work since LogOut has HttpPost attribute
}
This is the way I do it and it's using GET method, Is this what are you asking for ?
[HttpGet]
public ActionResult Logout()
{
WebSecurity.Logout();
// instead of displaying logout page directly we redirect to confirmation page.
// this will ensure auth cookie is cleared, which, in turn, ensures correct menu items are displayed
return RedirectToAction("LogoutConfirm");
}
[HttpGet]
public ActionResult LogoutConfirm()
{
return View();
}
Is your SomeActionOfSomeController present in Account Controller or some other other controller ?
If it is present in AccountController then you can do following thing instead of calling redicttoaction.
public ActionResult Index2()
{
return Index3();
}
[HttpPost]
public ActionResult Index3()
{
return Content("Test");
}
If it is from other controller action then you have to create object of AccountController and then call Method.
Hope this will help you.
You can do something like this right?
#using (Html.BeginForm("LogOff", "Account"))
{
#Html.AntiForgeryToken()
<button type="submit">Logout</button>
}
And you can do this, if you want a link, instead of button
#using (Html.BeginForm("LogOff", "Account",
FormMethod.Post, new { id = "LogOffForm" }))
{
#Html.AntiForgeryToken()
<a href="#Url.Action("LogOff", "Account")"
onclick="$('#LogOffForm').submit();">Logout</a>
}
Assuming you are implementing the default ASP.net login / logout, you can paste the following code in your Controller.
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
return RedirectToAction("Index", "Home");
Note: These two lines are the same code that are present in Account/Logoff Controller Action method.

Altering the ASP.NET MVC 2 ActionResult on HTTP post

I want to do some processing on a attribute before returning the view. If I set the appModel.Markup returned in the HttpPost ActionResult method below to "modified" it still says "original" on the form. Why cant I modify my attribute in a HttpGet ActionResult method?
[HttpGet]
public ActionResult Index()
{
return View(new MyModel
{
Markup = "original"
});
}
[HttpPost]
public ActionResult Index(MyModel appModel)
{
return View(new MyModel
{
Markup = "modified"
});
}
Because "original" is stored in ModelState. When form values are collected on MVC side, they are stored in ModelState object. You propably used Html.TextBox helper. When you recreate view after POST, it looks up into ModelState first and if there is posted value, it sets this value. Value in model object doesn't count anymore.
One of the solutions is to follow POST-REDIRECT-GET pattern. First POST, do something with data and then redirect:
[HttpPost]
public ActionResult Index(MyModel appModel)
{
//do something with data
return RedirectToAction("Index");
}
If you want to pass something between redirects, you can use TempData:
[HttpPost]
public ActionResult Index(MyModel appModel)
{
//do something with data
TempData["Something"] = "Hello";
return RedirectToAction("Index");
}
[HttpGet]
public ActionResult Index()
{
var something = TempData["Something"]; //after redirection it contains "Hello"
}
After redirect, ModelState is gone, so the is no value to override. POST-REDIRECT-GET pattern also helps to get rid of form reposting effect when you press F5 in browser.

asp.net mvc set action explicitly

I have 2 views for a input operation in my application.
The first view (lets call it view1) submits a form. Based on the form some operations on database is done and second view(View2) is returned with some other data from the database as a model.
controller action code :
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult View1(FormCollection fc)
{
//database ops to fill vm properties
View2ViewModel vm=new View2ViewModel();
return View("View2", vm);
}
Now, since I return a new view and not a action redirect the url is still http://www.url.com/View1 but everything works as it is supposed to.
The problem:
When I submit the form in View2 it calls the View1 action method, not the View2 action method. Probably because the url is still View1.
What can I do to call the action View2
Your controller methods should look something like this:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult View1(int id)
{
//database ops to fill vm properties
View1ViewModel vm=new View1ViewModel(id);
return View("View1", vm);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult View1(FormCollection fc)
{
// Code here to do something with FormCollection, and get id for
// View2 database lookup
return RedirectToAction("View2", id);
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult View2(int id)
{
// Do something with FormCollection
return View("View2", vm);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult View2(int id)
{
// Do something with FormCollection
return RedirectToAction("View3", id);
}
...and so on.
You can be in any View you want and submit the form to any controller's action from your application, cuz you can specify that
<% using (Html.BeginForm("ThAction", "Controller"))
{ %>
Enter your name: <%= Html.TextBox("name") %>
<input type="submit" value="Submit" />
<% } %>

Resources