ViewBag, ViewData y TempData


209

¿Podría algún cuerpo explicar cuándo usar

  1. TempData
  2. ViewBag
  3. Ver datos

Tengo un requisito, donde necesito establecer un valor en un controlador uno, ese controlador redirigirá al Controlador Dos y el Controlador Dos representará la Vista.

Intenté usar ViewBag, el valor se pierde cuando llego al controlador dos.

¿Puedo saber cuándo usar y ventajas o desventajas?

Gracias


55
Esta es una gran publicación que explica las diferencias.
Beku

1
stackoverflow.com/a/17199709/2015869
Imad Alazani

Respuestas:


293

1) TempData

Le permite almacenar datos que sobrevivirán para una redirección. Internamente utiliza la sesión como almacén de respaldo, después de que se realiza la redirección, los datos se expulsan automáticamente. El patrón es el siguiente:

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

Le permite almacenar datos en una acción del controlador que se utilizará en la vista correspondiente. Esto supone que la acción devuelve una vista y no redirige. Vive solo durante la solicitud actual.

El patrón es el siguiente:

public ActionResult Foo()
{
    ViewBag.Foo = "bar";
    return View();
}

y en la vista:

@ViewBag.Foo

o con ViewData:

public ActionResult Foo()
{
    ViewData["Foo"] = "bar";
    return View();
}

y en la vista:

@ViewData["Foo"]

ViewBages solo un contenedor dinámico ViewDatay existe solo en ASP.NET MVC 3.

Dicho esto, ninguna de esas dos construcciones debe usarse nunca. Debe usar modelos de vista y vistas fuertemente tipadas. Entonces el patrón correcto es el siguiente:

Ver modelo:

public class MyViewModel
{
    public string Foo { get; set; }
}

Acción:

public Action Foo()
{
    var model = new MyViewModel { Foo = "bar" };
    return View(model);
}

Vista fuertemente tipada:

@model MyViewModel
@Model.Foo

Después de esta breve introducción, respondamos su pregunta:

Mi requisito es que quiero establecer un valor en un controlador, ese controlador redirigirá a ControllerTwo y Controller2 representará la Vista.

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);
    }
}

y la vista correspondiente ( ~/Views/Two/Index.cshtml):

@model MyViewModel
@Html.DisplayFor(x => x.Foo)

También hay inconvenientes en el uso de TempData: si el usuario alcanza F5 en la página de destino, los datos se perderán.

Personalmente, tampoco uso TempData. Es porque internamente usa Session y desactivo la sesión en mis aplicaciones. Prefiero una forma más RESTANTE para lograr esto. Que es: en la primera acción del controlador que realiza la redirección, almacene el objeto en su almacén de datos y use la identificación única generada al redirigir. Luego, en la acción de destino, use esta identificación para recuperar el objeto almacenado 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);
    }
}

La vista se mantiene igual.


57
Gran respuesta, pero no estoy de acuerdo con la afirmación dogmática "ninguna de esas dos construcciones debe ser utilizada". He encontrado un par de usos legítimos para ViewBag. Por ejemplo, configuro una ViewBag.Titlepropiedad en todas mis Vistas que se usa en mi _Layout.cshtmlarchivo de vista base. Otro caso en el que lo uso es dar mensajes de información (por ejemplo, "¡Producto guardado con éxito!") A los usuarios. Puse un marcado genérico Layout.cshtmlpara representar un mensaje si se proporcionó y esto me permite configurar ViewBag.Messagecualquier Acción. Usar una propiedad ViewModel para cualquier caso tiene demasiadas desventajas.
Jesse Webb

22
Tendría que estar de acuerdo con Jesse, aunque esta es una excelente descripción, declarando descaradamente que no hay una buena razón para usar ViewBag es una cuestión de opinión, no de hecho. Sin duda, es una mala práctica usar demasiado la ViewBag, y algunos desarrolladores caen en esta trampa, pero con buen gusto es un recurso poderoso.
Ron DeFreitas

1
@ ron.defreitas, de acuerdo, dime una buena razón por la que usarías ViewBag. Describa un escenario específico del mundo real, cuando ViewBag tiene algún uso. Como usted dice que sí, cito un recurso poderoso , supongo que tiene algunos casos específicos en los que este poderoso recurso es poderoso . Como nunca lo he usado en mi carrera, estaría muy feliz de saber cómo la gente usa esta poderosa arma.
Darin Dimitrov

27
Tenemos un elitista por aquí. Darin, Jesse mencionó específicamente uno de esos ejemplos. El hecho de que siempre haya otras formas de hacer las cosas no niega automáticamente su utilidad.
Djentleman

2
@DarinDimitrov: Tengo un escenario en este momento en el que necesito pasar información a la vista desde un método de atributo. Usar filterContext.Controller.ViewData es sustancialmente más fácil que intentar pasarlo a una vista fuertemente tipada. Dicho esto, gracias por tu explicación, fue muy útil.
Andy

15

ASP.NET MVC nos ofrece tres opciones: ViewData, ViewBag y TempData para pasar datos del controlador a la vista y en la próxima solicitud. ViewData y ViewBag son casi similares y TempData realiza una responsabilidad adicional. Vamos a discutir u obtener puntos clave sobre esos tres objetos:

Similitudes entre ViewBag y ViewData:

  • Ayuda a mantener los datos cuando pasa del controlador a la vista.
  • Se utiliza para pasar datos del controlador a la vista correspondiente.
  • La vida corta significa que el valor se vuelve nulo cuando se produce la redirección. Esto se debe a que su objetivo es proporcionar una manera de comunicarse entre los controladores y las vistas. Es un mecanismo de comunicación dentro de la llamada al servidor.

Diferencia entre ViewBag y ViewData:

  • ViewData es un diccionario de objetos que se deriva de la clase ViewDataDictionary y accesible mediante cadenas como claves.
  • ViewBag es una propiedad dinámica que aprovecha las nuevas características dinámicas en C # 4.0.
  • ViewData requiere conversión de texto para tipos de datos complejos y verificar valores nulos para evitar errores.
  • ViewBag no requiere conversión de texto para tipos de datos complejos.

ViewBag & ViewData Ejemplo:

public ActionResult Index()
{
    ViewBag.Name = "Monjurul Habib";
    return View();
}


public ActionResult Index()
{
    ViewData["Name"] = "Monjurul Habib";
    return View();
} 

En vista:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData también es un diccionario derivado de la clase TempDataDictionary y se almacena en una sesión de corta vida y es una clave de cadena y un valor de objeto. La diferencia es que el ciclo de vida del objeto. TempData conserva la información durante el tiempo de una solicitud HTTP. Esto significa solo de una página a otra. Esto también funciona con una redirección 302/303 porque está en la misma solicitud HTTP. Ayuda a mantener los datos cuando se mueve de un controlador a otro controlador o de una acción a otra. En otras palabras, cuando redirige, "TempData" ayuda a mantener los datos entre esos redireccionamientos. Utiliza internamente variables de sesión. El uso de datos temporales durante la solicitud actual y posterior solo significa que se usa cuando está seguro de que la próxima solicitud se redirigirá a la vista siguiente. Requiere conversión de texto para tipos de datos complejos y verificar valores nulos para evitar errores.

public ActionResult Index()
{
  var model = new Review()
            {
                Body = "Start",
                Rating=5
            };
    TempData["ModelName"] = model;
    return RedirectToAction("About");
}

public ActionResult About()
{
    var model= TempData["ModelName"];
    return View(model);
}

El último mecanismo es la sesión, que funciona como ViewData, como un diccionario que toma una cadena de clave y un objeto de valor. Este se almacena en la cookie del cliente y se puede utilizar durante mucho más tiempo. También necesita más verificación para nunca tener información confidencial. Con respecto a ViewData o ViewBag, debe usarlo de manera inteligente para el rendimiento de la aplicación. Porque cada acción pasa por todo el ciclo de vida de la solicitud regular asp.net mvc. Puede usar ViewData / ViewBag en su acción secundaria, pero tenga cuidado de no usarla para llenar los datos no relacionados que pueden contaminar su controlador.


11

TempData

Básicamente es como un DataReader, una vez leído, los datos se perderán.

Mira este video

Ejemplo

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        String str = TempData["T"]; //Output - T
        return View();
    }
}

Si presta atención al código anterior, RedirectToAction no tiene ningún impacto sobre TempData hasta que se lea TempData. Entonces, una vez que se lee TempData, los valores se perderán.

¿Cómo puedo mantener TempData después de leer?

Verifique la salida en el Método de Acción Prueba 1 y Prueba 2

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        TempData["T"] = "T";
        return RedirectToAction("About");
    }

    public ActionResult About()
    {
        return RedirectToAction("Test1");
    }

    public ActionResult Test1()
    {
        string Str = Convert.ToString(TempData["T"]);
        TempData.Keep(); // Keep TempData
        return RedirectToAction("Test2");
    }

    public ActionResult Test2()
    {
        string Str = Convert.ToString(TempData["T"]); //OutPut - T
        return View();
    }
}

Si presta atención al código anterior, los datos no se pierden después de RedirectToAction, así como después de leer los datos y la razón es que estamos utilizando TempData.Keep(). es eso

De esta manera, puede hacer que persista tanto tiempo como desee en otros controladores también.

ViewBag / ViewData

Los datos persistirán en la vista correspondiente


4

TempData en Asp.Net MVC es una de las características muy útiles. Se utiliza para pasar datos de la solicitud actual a la solicitud posterior. En otras palabras, si queremos enviar datos de una página a otra mientras se produce la redirección, podemos usar TempData, pero debemos tener en cuenta el código para lograr esta función en MVC. Debido a que la vida de TempData es muy corta y permanece solo hasta que la vista de destino se carga por completo. Pero, podemos usar el método Keep () para conservar los datos en TempData.

Lee mas


3

ViewBag, ViewData, TempData y View State en MVC

http://royalarun.blogspot.in/2013/08/viewbag-viewdata-tempdata-and-view.html

ASP.NET MVC nos ofrece tres opciones: ViewData, VieBag y TempData para pasar datos del controlador a la vista y en la próxima solicitud. ViewData y ViewBag son casi similares y TempData realiza una responsabilidad adicional.

Similitudes entre ViewBag y ViewData:

Ayuda a mantener los datos cuando pasa del controlador a la vista. Se utiliza para pasar datos del controlador a la vista correspondiente. La vida corta significa que el valor se vuelve nulo cuando se produce la redirección. Esto se debe a que su objetivo es proporcionar una manera de comunicarse entre los controladores y las vistas. Es un mecanismo de comunicación dentro de la llamada al servidor.

Diferencia entre ViewBag y ViewData:

ViewData es un diccionario de objetos que se deriva de la clase ViewDataDictionary y accesible mediante cadenas como claves. ViewBag es una propiedad dinámica que aprovecha las nuevas características dinámicas en C # 4.0. ViewData requiere conversión de texto para tipos de datos complejos y verificar valores nulos para evitar errores. ViewBag no requiere conversión de texto para tipos de datos complejos.

ViewBag & ViewData Ejemplo:

public ActionResult Index()

{  
    ViewBag.Name = "Arun Prakash";
    return View();    
}

public ActionResult Index()  
{
    ViewData["Name"] = "Arun Prakash";
    return View(); 
}

En Vista, llamamos como a continuación:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Ayuda a mantener los datos cuando se mueve de un controlador a otro controlador o de una acción a otra. En otras palabras, cuando redirige, "Tempdata" ayuda a mantener los datos entre esos redireccionamientos. Utiliza internamente variables de sesión. TempData está destinado a ser una instancia de muy corta duración, y solo debe usarlo durante las solicitudes actuales y posteriores únicamente

El único escenario en el que usar TempData funcionará de manera confiable es cuando está redirigiendo. Esto se debe a que una redirección mata la solicitud actual (y envía el código de estado HTTP 302 Objeto movido al cliente), luego crea una nueva solicitud en el servidor para servir la vista redirigida.

Requiere conversión de texto para tipos de datos complejos y verificar valores nulos para evitar errores.

public ActionResult Index()
{   
   var model = new Review()  
   {  
      Body = "Start",  
      Rating=5  
   };  

    TempData["ModelName"] = model;    
    return RedirectToAction("About");   
} 

public ActionResult About()       
{  
    var model= TempData["ModelName"];  
    return View(model);   
}  

1
void Keep()

Calling this method with in the current action ensures that all the items in TempData are not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep(); // retains all strings values
    } 

void Keep(string key)

Calling this method with in the current action ensures that specific item in TempData is not removed at the end of the current request.

    @model MyProject.Models.EmpModel;
    @{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "About";
    var tempDataEmployeet = TempData["emp"] as Employee; //need typcasting
    TempData.Keep("emp"); // retains only "emp" string values
    } 

1

TempData siempre estará disponible hasta la primera lectura, una vez que lo lea ya no estará disponible, puede ser útil para pasar un mensaje rápido también para ver que desaparecerá después de la primera lectura. ViewBag Es más útil cuando se pasan datos rápidamente a la vista, normalmente debe pasar todos los datos a la vista a través del modelo, pero hay casos en los que el modelo proviene directamente de la clase que se asigna a la base de datos como el marco de la entidad en ese caso No importa qué cambiar su modelo para pasar una nueva pieza de datos, puede pegarlo en la vista ViewData es solo una versión indexada de ViewBag y se usó antes de MVC3


0

Además, el alcance es diferente entre viewbag y temptdata. viewbag se basa en la primera vista (no se comparte entre los métodos de acción) pero los datos temporales se pueden compartir entre un método de acción y solo entre sí.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.