Soru ASP.NET MVC'deki ViewBag, sahne arkasında nasıl çalışır?


ASP.NET MVC'de bir kitap okuyorum ve aşağıdaki örnekte nasıl çalıştığını merak ediyorum:

Örnek 1

kontrolör

public class MyController : Controller
{
    public ActionResult Index()
    {
        ViewBag.MyProperty = 5;

        return View();
    }
}

Görünüm

<h1>@ViewBag.MyProperty</h1>

Şimdi anladım ki ViewBag dinamik bir nesnedir, bu yüzden özelliği kurabilirsiniz (dinamik nesneler hakkında fazla bir şey bilmese de, onlarla hiç çalışmadım.) Ancak görünüm, belirli bir örneği nasıl alır? ViewBag Kontrolörden, doğrudan bir şey geçmemize rağmen?

Bunu düşündüm ViewBag bir olabilir public  static nesne, ancak sonra herhangi bir değişiklik genel olurdu ve bir görünüm örneğine özgü olmaz.

Bunun perde arkasında nasıl çalıştığını açıklayabilir misiniz?

Örnek 2

kontrolör

public class MyController : Controller
{
    public ActionResult Index()
    {
        ViewBag.MyProperty = 5;

        return View();
    }

    public ActionResult Index2()
    {
        ViewBag.MyProperty = 6;

        return View();
    }
}

Şimdi diyelim Index yöntem ilk olarak adlandırılır ve daha sonra Index2. Sonunda değeri ViewBag.MyProperty 6 olarak bitecek Index2). Yapmanın iyi bir şey olmadığını hissediyorum, ancak aynı zamanda masaüstü geliştirme terimlerinde düşündüğümü hissediyorum. Belki de web sitesi vatansız olduğu için ASP.NET MVC ile kullanıldığında önemli değildir. Bu dava mı?


30
2018-06-05 20:40


Menşei


Bunu hayal ediyorum ViewBag nesne denetleyici nesnesiyle basitçe örnek özniteliği olarak başlatılır. static). - Robert Harvey♦
Aslında denetleyicinin bir üyesi olduğunu görebilirsiniz: msdn.microsoft.com/en-us/library/... - McGarnagle
Farklı görünümler döndüren iki yöntem varsa, aynı özelliği ViewBag örneğin, birbirini etkileyebilir mi? Bu bir sorun olmaz mıydı? Yine de masaüstü geliştirmede hala düşünüyorum düşünüyorum. - hattenn
Denetleyici başlatıldığında Index() denir ve sonra bertaraf edilir return View(); Idam edildi. Yani ViewBag İstek tamamlandığında kapsam dışı kalır. Bu yüzden ViewBag özellikler isteklerin arasında kalmaz. - Robert Harvey♦
@RobertHarvey, tamam o zaman. Şimdi mantıklı. Ne zaman ortaya çıktığını bilmiyordum. Dediğim gibi, hala masaüstü geliştirme yolunda düşünüyorum. Bunları bir cevap olarak yazabilir misiniz, kabul edilen cevap olarak seçeceğim. - hattenn


Cevaplar:


ViewBag bir özelliğidir ControllerBaseTüm denetleyicilerin miras alması gerekir. Bu bir dynamic Nesne, bu yüzden derleme zamanı hataları almadan yeni özellikler ekleyebilirsiniz.

Değil staticBu nesnenin bir üyesi. İstek ömrü boyunca, denetleyici örneği oluşturulur ve atılır; böylece, değerin üzerine yazmak gibi "eşzamanlılık" sorunlarına sahip olmazsınız.

View (ve türevleri) yöntemi değil static yanı sıra, görünüm bu şekilde alır ViewBag değerler: görünümü oluşturma işlemi sırasında denetleyici örneği de ViewBag örneğine sahiptir.


27
2018-06-05 21:13



ViewBag bir özelliğidir WebViewPage de. atandığı verileri nasıl alır ControllerBase.ViewBag özelliği. Detaylandırır mısınız lütfen? - Abi
@Abi görünümü, kontrolörden ActionResult oluşturuluyor. ASP.NET Core MVC'yi örnek olarak alırsak, bunu görebilirsiniz. ViewContext onu ctorda alır: github.com/aspnet/Mvc/blob/dev/src/... - Andre Calil


Analiz ederseniz ControllerBase ViewBag özelliği, kaynağınızın daha güzel görünmesi için ViewData özelliğinin "proxy" olduğunu görürsünüz. (Hatta Phil Haack'den, Phil'in ViewBag özelliğini ViewData'ya bir kısayol olarak tanıttı ve tekrarlanan köşeli parantez ve tırnakların ihtiyacını ortadan kaldırarak görüşme yapan Scott Hanselman'ı hatırladığını hatırlıyorum). Buna rağmen ViewBag özellik olarak açığa çıkar dynamic nesne uygular DynamicViewDataDictionary ViewData ile doğrudan çalışan sınıf.

Kaynak koduna bakmak kontrolör sınıf bu yöntemi bulabilirsiniz:

protected internal virtual ViewResult View(string viewName, string masterName, object model)

Yani temelde aradığınızda return View(); kontrol cihazınızdan yeni bir örnek oluşturur ActionResult Denetleyiciden denetleyiciye ViewData geçiren sınıf. Örneği ActionResult daha sonra belirli bir görünüm motoruna (ASPX, Razor) aktarılır, böylece söz konusu görünümü oluşturmak için kullanılabilir.

ViewBag / ViewData genel statik yapmak zararlı olabilir. MVC uygulamanızın her bir web isteği yeni bir kontrolör örneği oluşturur. Eğer ViewData / ViewBag'i genel statik olarak kullanmışsanız, iki eşzamanlı kullanıcı aynı verileri ViewBag / ViewData'dan paylaşır.

İşte bir video. ViewBag (formder ViewModel) ile ilgili tartışma 04:05 de başlıyor


10
2018-06-05 21:17





ViewBag bir özelliğidir ControllerBase. Aşağıdaki şekilde tanımlanmıştır:

public Object ViewBag { get; }

Bu imzanın aslında yanlış olduğunu unutmayın. Kaynak kodun gerçekte nasıl göründüğü aşağıda açıklanmıştır:

public dynamic ViewBag {
        get {
            if (_dynamicViewDataDictionary == null) {
                _dynamicViewDataDictionary = new DynamicViewDataDictionary(() => ViewData);
            }
            return _dynamicViewDataDictionary;
        }
    }

_dynamicViewDataDictionary bir ExpandoObject'dir; çalışma zamanında ona özellik ekleyebilirsiniz. Ömrü, HTTP isteğinin kullanım ömrü olan denetleyicininkiyle aynı.


6
2018-06-05 21:27



ControllerBase'in ViewBag özelliğinin sürekli olarak dinamik olarak tanımlandığı anlaşılıyor. public dynamic ViewBag { get; } - brntsllvn
ViewBag, WebViewPage'in bir özelliğidir. ControllerBase.ViewBag özelliğine atanan verileri nasıl alır. Detaylandırır mısınız lütfen? - Abi