ViewBag, ViewData и TempData

209

Может ли любое тело объяснить, когда использовать

  1. TempData
  2. ViewBag
  3. ViewData

У меня есть требование, когда мне нужно установить значение в контроллере один, этот контроллер будет перенаправлять на контроллер два, а контроллер два будет отображать представление.

Я пытался использовать ViewBag, значение теряется, когда я достигаю второго контроллера.

Могу ли я знать, когда использовать и преимущества или недостатки?

Спасибо

Хари Гиллала
источник
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. Это потому, что внутри он использует Сессию, и я отключаю сессию в своих приложениях. Я предпочитаю более RESTful способ достичь этого. Что: в первом действии контроллера, которое выполняет перенаправление, сохраните объект в вашем хранилище данных и используйте сгенерированный уникальный идентификатор при перенаправлении. Затем на целевом действии используйте этот идентификатор для извлечения первоначально сохраненного объекта:

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

Последний механизм - это Session, который работает как ViewData, как Dictionary, который принимает строку для ключа и объект для значения. Этот файл сохраняется в cookie-файле клиента и может использоваться гораздо дольше. Кроме того, необходимо больше проверки, чтобы никогда не иметь никакой конфиденциальной информации. Что касается ViewData или ViewBag, вы должны использовать его разумно для производительности приложений. Потому что каждое действие проходит весь жизненный цикл регулярного запроса asp.net mvc. Вы можете использовать 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
    } 
Saineshwar
источник
1

TempData будет всегда доступен до первого чтения, после того как вы прочитаете его, он больше не будет доступен, может быть полезно также передать быстрое сообщение, чтобы просмотреть, что будет пропущено после первого чтения. ViewBag Более полезно при быстрой передаче фрагмента данных в представление, обычно вы должны передавать все данные в представление через модель, но есть случаи, когда вы моделируете поступление непосредственно из класса, который отображается в базу данных, как структура сущностей, в этом случае вы не используете Что бы изменить вашу модель, чтобы передать новый фрагмент данных, вы можете вставить это в viewbag ViewData это просто индексированная версия ViewBag и использовалась до MVC3

Дэвид Фози
источник
0

Кроме того, область видимости отличается между viewbag и temptdata. viewbag основан на первом представлении (не разделяемом между методами действия), но temptdata может быть разделена между методом действия и только между собой.

Elnaz
источник