Actually, the data you send using the ViewBag can be sent back to the controller via GET and POST parameters (its how ALL data are sent back). More about get and post
The following is an example on passing data back and forth using ViewBag (output) and <input type="hidden" />
(input)
public class HomeController : Controller
{
public ViewResult Edit()
{
// Lets send this one, and see if the view can return it.
ViewBag.UserID = 1;
return View();
}
[HttpPost]
public ActionResult Edit(int userID)
{
int userID = userID; // Place a breakpoint here and verify our little test.
return View();
}
}
// This is your view
@using (Html.BeginForm()) {
<input type="hidden" value="@ViewBag.UserID" />
<input type="submit" value="Save" />
}
Managing the State
Using ViewBag for passing the state is not uncommon, like for instance managing the page index for a paging functionality. In those cases, we wouldn't want to create a ViewModel just for a single property(PageIndex) that has no relation whatsoever with the model. As long as your intentions are obvious, then I would say keep it simple.
The proper usage of sessions depends on the type of state that you are trying maintain (and the business requirement). If you are managing the state of the UI using sessions, then that is bad. But if you are trying to protect the state like a user account id, in a site that demands security like banking website, then sessions are highly recommended if not the only acceptable.
Session is a tool, and like most tools, if abused are frowned upon.
Different types of state should be manage not by one method, but by many different methods.
Ways to manage the state