ViewBag, ViewData และ TempData


209

มีร่างกายใดสามารถอธิบายเมื่อใช้

  1. TempData
  2. ViewBag
  3. ViewData

ฉันมีข้อกำหนดที่ฉันต้องตั้งค่าในคอนโทรลเลอร์หนึ่งคอนโทรลเลอร์นั้นจะเปลี่ยนเส้นทางไปที่ Controller Two และ Controller Two จะแสดงมุมมอง

ฉันได้ลองใช้ ViewBag แล้วค่าจะหายไปเมื่อฉันไปถึง Controller Two

ฉันจะรู้ได้อย่างไรว่าจะใช้และข้อดีหรือข้อเสียเมื่อใด

ขอบคุณ


5
นี่คือโพสต์ที่ยอดเยี่ยมที่อธิบายถึงความแตกต่าง
Beku

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

2
ตรวจสอบViewData
2794034

คำตอบ:


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เป็นเพียง wrapper แบบไดนามิกรอบ ๆ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 เป็นเพราะภายในใช้เซสชันและฉันปิดใช้งานเซสชันในแอปพลิเคชันของฉัน ฉันชอบวิธีที่สงบมากขึ้นเพื่อบรรลุเป้าหมายนี้ ซึ่งคือ: ในการดำเนินการควบคุมครั้งแรกที่ดำเนินการจัดเก็บการเปลี่ยนเส้นทางวัตถุในที่เก็บข้อมูลของคุณและผู้ใช้ ID ที่ไม่ซ้ำกันสร้างขึ้นเมื่อเปลี่ยนเส้นทาง จากนั้นในการดำเนินการเป้าหมายให้ใช้รหัสนี้เพื่อดึงวัตถุที่เก็บไว้ในตอนแรกกลับมา:

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 สำหรับทั้งสองกรณีมีข้อเสียมากเกินไป
Jesse Webb

22
ฉันต้องเห็นด้วยกับ Jesse ในขณะที่นี่เป็นคำอธิบายที่ยอดเยี่ยมโจ๋งครึ่มระบุว่าไม่มีเหตุผลที่ดีที่จะใช้ ViewBag เป็นเรื่องของความเห็นไม่ใช่เรื่องจริง แน่นอนว่าเป็นวิธีปฏิบัติที่ไม่ดีที่จะใช้ ViewBag มากเกินไปและนักพัฒนาบางรายตกอยู่ในกับดักนี้ แต่ใช้อย่างมีรสนิยมว่าเป็นทรัพยากรที่มีประสิทธิภาพ
Ron DeFreitas

1
@ ron.defreitas เอาล่ะบอกฉันด้วยเหตุผลหนึ่งข้อว่าทำไมคุณถึงใช้ ViewBagไม่เป็นไรบอกฉันแล้วหนึ่งในเหตุผลที่ว่าทำไมคุณจะใช้ โปรดอธิบายสถานการณ์ในโลกแห่งความเป็นจริงที่เฉพาะเจาะจงเมื่อ ViewBag มีประโยชน์ เนื่องจากคุณจะบอกว่ามันเป็นสิ่งที่ผมพูดทรัพยากรที่มีประสิทธิภาพผมคิดว่าคุณมีเฉพาะบางกรณีที่นี้ทรัพยากรที่มีประสิทธิภาพเป็นที่มีประสิทธิภาพ เนื่องจากฉันไม่เคยใช้มันในอาชีพการงานของฉันฉันจึงมีความสุขมากที่ได้เรียนรู้ว่าผู้คนใช้อาวุธทรงพลังนี้อย่างไร
ดารินทร์ดิมิทรอฟ

27
เรามีชนชั้นนำที่นี่ ดาริน, เจสซีได้กล่าวถึงตัวอย่างหนึ่งดังกล่าวโดยเฉพาะ เพียงเพราะมีวิธีอื่น ๆ ในการทำสิ่งต่าง ๆ ไม่ได้เป็นการลบล้างประโยชน์ของพวกเขาโดยอัตโนมัติ
Djentleman

2
@DarinDimitrov: ฉันมีสถานการณ์ตอนนี้ที่ฉันต้องส่งข้อมูลบางอย่างไปยังมุมมองจากภายในวิธีการแอตทริบิวต์ การใช้ filterContext.Controller.ViewData นั้นง่ายกว่าการส่งผ่านไปยังมุมมองที่พิมพ์ ที่กล่าวว่าขอบคุณสำหรับคำอธิบายของคุณมันมีประโยชน์มาก
Andy

15

ASP.NET MVC เสนอตัวเลือกสามตัวให้กับ ViewData, ViewBag และ TempData สำหรับการส่งข้อมูลจากคอนโทรลเลอร์ไปยังมุมมองและในคำขอถัดไป ViewData และ ViewBag เกือบจะคล้ายกันและ TempData ดำเนินการรับผิดชอบเพิ่มเติม ให้พูดคุยหรือรับประเด็นสำคัญเกี่ยวกับวัตถุทั้งสามนี้:

ความคล้ายคลึงกันระหว่าง ViewBag และ ViewData:

  • ช่วยในการรักษาข้อมูลเมื่อคุณย้ายจากคอนโทรลเลอร์ไปยังมุมมอง
  • ใช้เพื่อส่งผ่านข้อมูลจากคอนโทรลเลอร์ไปยังมุมมองที่สอดคล้องกัน
  • อายุการใช้งานสั้นหมายถึงค่ากลายเป็นค่าว่างเมื่อมีการเปลี่ยนเส้นทาง นี่เป็นเพราะเป้าหมายของพวกเขาคือการให้วิธีการสื่อสารระหว่างตัวควบคุมและมุมมอง มันเป็นกลไกการสื่อสารภายในการโทรของเซิร์ฟเวอร์

ความแตกต่างระหว่าง ViewBag และ ViewData:

  • ViewData เป็นพจนานุกรมของวัตถุที่ได้มาจากคลาส ViewDataDictionary และเข้าถึงได้โดยใช้สตริงเป็นกุญแจ
  • ViewBag เป็นคุณสมบัติแบบไดนามิกที่ใช้ประโยชน์จากคุณลักษณะแบบไดนามิกใหม่ใน C # 4.0
  • ViewData ต้องการ typecasting สำหรับชนิดข้อมูลที่ซับซ้อนและตรวจสอบค่า Null เพื่อหลีกเลี่ยงข้อผิดพลาด
  • 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” ช่วยรักษาข้อมูลระหว่างการเปลี่ยนเส้นทางเหล่านั้น มันใช้ตัวแปรเซสชันภายใน ข้อมูลชั่วคราวใช้ระหว่างคำขอปัจจุบันและคำขอถัดไปเท่านั้นหมายความว่าใช้เมื่อคุณแน่ใจว่าคำขอถัดไปจะเปลี่ยนเส้นทางไปยังมุมมองถัดไป มันต้องการ typecasting สำหรับชนิดข้อมูลที่ซับซ้อนและตรวจสอบค่า Null เพื่อหลีกเลี่ยงข้อผิดพลาด

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 เช่นพจนานุกรมที่ใช้สตริงสำหรับคีย์และวัตถุสำหรับค่า อันนี้ถูกเก็บไว้ในคุกกี้ลูกค้าและสามารถใช้งานได้นานขึ้น นอกจากนี้ยังต้องมีการตรวจสอบเพิ่มเติมเพื่อไม่ให้มีข้อมูลลับใด ๆ เกี่ยวกับ 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 หลังจากอ่านได้อย่างไร

ตรวจสอบผลลัพธ์ใน Action Method Test 1 และ Test 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 ต้องการ typecasting สำหรับชนิดข้อมูลที่ซับซ้อนและตรวจสอบค่า Null เพื่อหลีกเลี่ยงข้อผิดพลาด 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 วัตถุย้ายไปยังลูกค้า) จากนั้นสร้างคำขอใหม่บนเซิร์ฟเวอร์เพื่อให้บริการมุมมองที่เปลี่ยนเส้นทาง

มันต้องการ typecasting สำหรับชนิดข้อมูลที่ซับซ้อนและตรวจสอบค่า Null เพื่อหลีกเลี่ยงข้อผิดพลาด

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 มีประโยชน์มากขึ้นเมื่อส่งชิ้นส่วนข้อมูลอย่างรวดเร็วไปยังมุมมองโดยปกติคุณควรส่งข้อมูลทั้งหมดไปยังมุมมองผ่านโมเดล แต่มีบางกรณีที่คุณจำลองแบบโดยตรงจากคลาสที่แมปเข้าสู่ฐานข้อมูลเช่นเฟรมเวิร์กเอนทิตี้ในกรณีนี้ สิ่งที่จะเปลี่ยนรูปแบบของคุณที่จะส่งชิ้นส่วนของข้อมูลใหม่คุณสามารถติดที่ viewbag ViewData เป็นเพียงดัชนีรุ่นของ ViewBag และถูกนำมาใช้ก่อน MVC3


0

ขอบเขตยังแตกต่างกันระหว่าง viewbag และ temptdata viewbag อิงตามมุมมองแรก (ไม่แชร์ระหว่างวิธีการกระทำ) แต่ temptdata สามารถใช้ร่วมกันระหว่างวิธีการกระทำกับอีกวิธีหนึ่งได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.