1) TempData
Permite armazenar dados que sobreviverão a um redirecionamento. Internamente, ele usa a Sessão como armazenamento de backup, depois que o redirecionamento é feito, os dados são despejados automaticamente. O padrão é o seguinte:
public ActionResult Foo()
{
// store something into the tempdata that will be available during a single redirect
TempData["foo"] = "bar";
// you should always redirect if you store something into TempData to
// a controller action that will consume this data
return RedirectToAction("bar");
}
public ActionResult Bar()
{
var foo = TempData["foo"];
...
}
2) ViewBag, ViewData
Permite armazenar dados em uma ação do controlador que será usada na visualização correspondente. Isso pressupõe que a ação retorne uma exibição e não redirecione. Vive apenas durante a solicitação atual.
O padrão é o seguinte:
public ActionResult Foo()
{
ViewBag.Foo = "bar";
return View();
}
e na vista:
@ViewBag.Foo
ou com ViewData:
public ActionResult Foo()
{
ViewData["Foo"] = "bar";
return View();
}
e na vista:
@ViewData["Foo"]
ViewBag
é apenas um invólucro dinâmico ViewData
e existe apenas no ASP.NET MVC 3.
Dito isto, nenhuma dessas duas construções deve ser usada. Você deve usar modelos de vista e vistas fortemente tipadas. Portanto, o padrão correto é o seguinte:
Ver modelo:
public class MyViewModel
{
public string Foo { get; set; }
}
Açao:
public Action Foo()
{
var model = new MyViewModel { Foo = "bar" };
return View(model);
}
Visualização fortemente tipada:
@model MyViewModel
@Model.Foo
Após esta breve introdução, vamos responder à sua pergunta:
Meu requisito é que eu quero definir um valor em um controlador, esse controlador será redirecionado para ControllerTwo e Controller2 renderizará a View.
public class OneController: Controller
{
public ActionResult Index()
{
TempData["foo"] = "bar";
return RedirectToAction("index", "two");
}
}
public class TwoController: Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Foo = TempData["foo"] as string
};
return View(model);
}
}
e a vista correspondente ( ~/Views/Two/Index.cshtml
):
@model MyViewModel
@Html.DisplayFor(x => x.Foo)
Também existem desvantagens em usar o TempData: se o usuário pressionar F5 na página de destino, os dados serão perdidos.
Pessoalmente, também não uso o TempData. É porque internamente ele usa Session e eu desabilito a sessão nos meus aplicativos. Eu prefiro uma maneira mais RESTful de conseguir isso. O que é: na primeira ação do controlador que executa o redirecionamento, armazene o objeto no seu repositório de dados e use o ID exclusivo gerado ao redirecionar. Em seguida, na ação de destino, use esse ID para recuperar o objeto armazenado inicialmente:
public class OneController: Controller
{
public ActionResult Index()
{
var id = Repository.SaveData("foo");
return RedirectToAction("index", "two", new { id = id });
}
}
public class TwoController: Controller
{
public ActionResult Index(string id)
{
var model = new MyViewModel
{
Foo = Repository.GetData(id)
};
return View(model);
}
}
A vista permanece a mesma.