ViewBag, ViewData та TempData


209

Чи може пояснити будь-який орган, коли його використовувати

  1. TempData
  2. ViewBag
  3. ViewData

У мене є вимога, коли мені потрібно встановити значення в контролері один, що контролер буде перенаправляти на контролер два, а контролер два - надавати подання.

Я спробував використати ViewBag, значення втрачається в той час, коли я дістаюся до Controller Two.

Чи можу я знати, коли використовувати та переваги чи недоліки?

Дякую


5
Це чудовий пост, який пояснює відмінності.
Беку

1
stackoverflow.com/a/17199709/2015869
Імад Алазані

2
Перевірте це ViewData Vs ViewBag Vs TempData
user2794034

Відповіді:


293

1) TempData

Дозволяє зберігати дані, які збережуться для переадресації. Внутрішньо він використовує сеанс як резервне зберігання, після перенаправлення дані автоматично вилучаються. Схема наступна:

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

Дозволяє зберігати дані в дії контролера, які будуть використані у відповідному вікні. Це передбачає, що дія повертає перегляд і не перенаправляє. Живе лише під час поточного запиту.

Схема наступна:

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

і в перегляді:

@ViewBag.Foo

або з ViewData:

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

і в перегляді:

@ViewData["Foo"]

ViewBagє просто динамічною обгорткою навколо ViewDataі існує лише в ASP.NET MVC 3.

Як було сказано, жодна з цих двох конструкцій ніколи не повинна використовуватися. Слід використовувати моделі перегляду та сильно набрані види. Тож правильний зразок такий:

Переглянути модель:

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

Дія:

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

Сильно набраний вид:

@model MyViewModel
@Model.Foo

Після цього короткого вступу давайте відповімо на ваше запитання:

Моя вимога полягає в тому, що я хочу встановити значення в контролері, яке контролер перенаправить на ControllerTwo, а Controller2 візуалізує перегляд.

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

і відповідний вид ( ~/Views/Two/Index.cshtml):

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

Існують і недоліки використання TempData: якщо користувач потрапить на F5 на цільовій сторінці, дані будуть втрачені.

Особисто я також не використовую TempData. Це тому, що внутрішньо він використовує сесію, і я відключаю сеанс у своїх програмах. Я віддаю перевагу більш РЕАЛЬНИЙ спосіб досягти цього. Що полягає: у першій дії контролера, який виконує переадресацію, зберігається об’єкт у вашому сховищі даних та користувачеві створюється унікальний ідентифікатор під час перенаправлення. Потім в цільовій дії використовуйте цей ідентифікатор, щоб отримати спочатку збережений об'єкт:

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

Вид залишається однаковим.


57
Чудова відповідь, але я не згоден з догматичним твердженням: "жоден із цих двох конструкцій ніколи не повинен використовуватися". Я знайшов пару законних звичок для ViewBag. Наприклад, я встановив ViewBag.Titleвластивість для всіх своїх переглядів, які використовуються в моєму _Layout.cshtmlбазовому файлі перегляду. Інший випадок, коли я його використовую - це надання інформаційних повідомлень (наприклад, "Продукт успішно збережено!") Для користувачів. Я розмістив деяку загальну розмітку, Layout.cshtmlщоб надати повідомлення, якщо воно передбачене, і це дозволяє мені встановлювати ViewBag.Messageбудь-яку дію. Використання властивості ViewModel в будь-якому випадку має занадто багато недоліків.
Джессі Вебб

22
Я мав би погодитися з Джессі, хоча це чудовий опис, нахабно заявляючи, що немає вагомих причин використовувати ViewBag - це питання думки, не факт. Це, звичайно, погана практика зловживати ViewBag, і деякі розробники потрапляють у цю пастку, але зі смаком використаний це потужний ресурс.
Рон ДеФрейтас

1
@ ron.defreitas, гаразд, скажи мені тоді одну хорошу причину, чому б ти користувався ViewBag. Опишіть, будь ласка, конкретний сценарій у реальному світі, коли ViewBag має певну користь. Оскільки ви говорите, що це так, я цитую потужний ресурс , я думаю, у вас є конкретні випадки, коли цей потужний ресурс є потужним . Оскільки я ніколи не використовував це у своїй кар’єрі, я був би дуже радий дізнатися, як люди використовують цю потужну зброю.
Дарин Димитров

27
У нас тут елітист. Дарин, Джессі спеціально згадав про один такий приклад. Тільки тому, що завжди є інші способи робити речі, це автоматично не заперечує їх корисності.
Дженнтман

2
@DarinDimitrov: Зараз у мене є сценарій, коли мені потрібно передати деяку інформацію перегляду в межах методу атрибутів. Використовувати filterContext.Controller.ViewData суттєво простіше, ніж намагатися передати його в сильно набраний вид. Це сказало, дякую за ваше пояснення, було дуже корисно.
Енді

15

ASP.NET MVC пропонує нам три варіанти ViewData, ViewBag і TempData для передачі даних з контролера для перегляду та наступного запиту. ViewData та ViewBag майже схожі, і TempData несе додаткову відповідальність. Дозволяє обговорити або отримати ключові моменти щодо цих трьох об’єктів:

Подібність між ViewBag та ViewData:

  • Допомагає зберігати дані при переході від контролера до перегляду.
  • Використовується для передачі даних від контролера до відповідного подання.
  • Короткий термін означає, що значення стає недійсним, коли відбувається перенаправлення. Це тому, що їх мета полягає в тому, щоб забезпечити спосіб спілкування між контролерами та поглядами. Це механізм зв'язку в серверному дзвінку.

Різниця між ViewBag та ViewData:

  • ViewData - це словник об'єктів, який походить із класу ViewDataDictionary і доступний за допомогою рядків як ключів.
  • ViewBag - це динамічна властивість, яка використовує нові динамічні функції в C # 4.0.
  • ViewData вимагає набору тексту для складного типу даних та перевірки на нульові значення, щоб уникнути помилок.
  • ViewBag не вимагає набору тексту для складного типу даних.

Приклад ViewBag & ViewData:

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


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

У перегляді:

@ViewBag.Name 
@ViewData["Name"] 

TempData:

TempData також є словником, похідним від класу TempDataDictionary і зберігається в сесії короткого життя, і це рядковий ключ та значення об'єкта. Різниця полягає в тому, що життєвий цикл об’єкта. TempData зберігає інформацію на час запиту HTTP. Це означає лише з однієї сторінки на іншу. Це також працює з перенаправленням 302/303, оскільки воно знаходиться в тому самому HTTP-запиті. Допомагає зберігати дані при переході від одного контролера до іншого контролера або від однієї дії до іншої дії. Іншими словами, коли ви переспрямовуєте, "TempData" допомагає зберігати дані між цими переадресаціями. Він внутрішньо використовує змінні сеансу. Тимчасові дані, що використовуються під час поточного та наступного запиту, означають, що вони використовуються лише тоді, коли ви впевнені, що наступний запит буде переспрямовано на наступний вигляд. Він вимагає введення тексту для складного типу даних і перевіряти нульові значення, щоб уникнути помилок.

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

Останній механізм - це сесія, яка працює як ViewData, як словник, який приймає рядок для ключа та об'єкт за значенням. Цей файл зберігається у файлі cookie клієнта і може використовуватися набагато довший час. Також потрібно більше перевірки, щоб ніколи не було конфіденційної інформації. Щодо ViewData або ViewBag, то ви повинні використовувати його розумно для роботи програми. Тому що кожна дія проходить протягом усього життєвого циклу регулярного запиту mvc на asp.net. Ви можете використовувати ViewData / ViewBag у своїй дитині, але будьте обережні, щоб не використовувати його для заповнення непов'язаних даних, які можуть забруднити ваш контролер.


11

TempData

В основному це схоже на DataReader, щойно прочитані, дані будуть втрачені.

Перевірте це відео

Приклад

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

Якщо ви звернете увагу на вищезазначений код, RedirectToAction не впливає на TempData, поки не буде прочитано TempData. Отже, як тільки TempData буде прочитана, значення втрачаються.

Як я можу зберегти TempData після читання?

Перевірте вихід у Тестовому способі дій 1 та Тесті 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();
    }
}

Якщо ви звернете увагу на вищезазначений код, дані не втрачаються після RedirectToAction, а також після читання даних, і причина в тому, що ми використовуємо TempData.Keep(). чи це

Таким чином ви можете змусити його зберігатись так довго, як хочете, і в інших контролерах.

ViewBag / ViewData

Дані зберігатимуться у відповідному перегляді


4

TempData в Asp.Net MVC - одна з дуже корисних функцій. Він використовується для передачі даних від поточного запиту до наступного запиту. Іншими словами, якщо ми хочемо надсилати дані з однієї сторінки на іншу сторінку під час перенаправлення, ми можемо використовувати TempData, але для досягнення цієї функції в MVC нам потрібно зробити деякий розгляд у коді. Оскільки термін служби TempData дуже короткий і лежить лише до повного завантаження цільового виду. Але ми можемо використовувати метод Keep () для збереження даних у TempData.

Детальніше


3

ViewBag, ViewData, TempData та View State в MVC

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

ASP.NET MVC пропонує нам три варіанти ViewData, VieBag і TempData для передачі даних з контролера для перегляду та наступного запиту. ViewData та ViewBag майже схожі, і TempData несе додаткову відповідальність.

Подібність між ViewBag та ViewData:

Допомагає зберігати дані при переході від контролера до перегляду. Використовується для передачі даних від контролера до відповідного подання. Короткий термін означає, що значення стає недійсним, коли відбувається перенаправлення. Це тому, що їх мета полягає в тому, щоб забезпечити спосіб спілкування між контролерами та поглядами. Це механізм зв'язку в серверному дзвінку.

Різниця між ViewBag та ViewData:

ViewData - це словник об'єктів, який походить із класу ViewDataDictionary і доступний за допомогою рядків як ключів. ViewBag - це динамічна властивість, яка використовує нові динамічні функції в C # 4.0. ViewData вимагає набору тексту для складного типу даних та перевірки на нульові значення, щоб уникнути помилок. ViewBag не вимагає набору тексту для складного типу даних.

Приклад ViewBag & ViewData:

public ActionResult Index()

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

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

У перегляді ми дзвонимо так, як нижче:

@ViewBag.Name   
@ViewData["Name"]

TempData:

Допомагає зберігати дані при переході від одного контролера до іншого контролера або від однієї дії до іншої дії. Іншими словами, коли ви переспрямовуєте, "Tempdata" допомагає зберігати дані між цими переадресаціями. Він внутрішньо використовує змінні сеансу. TempData призначений для дуже короткочасного екземпляра, і використовувати його слід лише під час поточних та наступних запитів

Єдиний сценарій, коли використання TempData надійно працюватиме, коли ви перенаправляєтесь. Це відбувається через те, що переспрямовування вбиває поточний запит (і надсилає клієнту код статусу HTTP 302 Об'єкт, переміщений), а потім створює новий запит на сервері для обслуговування переспрямованого подання.

Він вимагає введення тексту для складного типу даних і перевіряти нульові значення, щоб уникнути помилок.

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 буде завжди доступною до першого читання, як тільки ви прочитаєте її, вона вже не доступна, може бути корисною для передачі швидкого повідомлення, а також для перегляду, яке буде втрачене після першого читання. ViewBag Більш корисно, коли швидко передавати фрагмент даних у подання, як правило, ви повинні передавати всі дані перегляду через модель, але бувають випадки, коли ви моделюєте безпосередньо з класу, який відображається в базу даних, як структура сутності, у цьому випадку ви 'що робити, щоб змінити вашу модель для передачі нового фрагмента даних, ви можете вставити те, що у вікні перегляду ViewData є просто індексованою версією ViewBag і використовувався до MVC3


0

Також сфера застосування відрізняється між вікном перегляду та темпдатом. Пакет перегляду базується на першому огляді (не поділяється між методами дій), але тимчасові дані можуть ділитися між методом дії та лише один одним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.