ASP.NET MVC 'de ana sayfaya veri iletme


Yanıtlar:


77

Görünümlerinizin güçlü bir şekilde yazılmış görünüm veri sınıflarına sahip olmasını tercih ediyorsanız, bu sizin için uygun olabilir. Diğer çözümler muhtemelen daha doğrudur ancak bu, tasarım ve pratiklik IMHO arasında güzel bir denge.

Ana sayfa, yalnızca kendisiyle ilgili bilgileri içeren güçlü bir şekilde yazılmış bir görünüm veri sınıfını alır:

public class MasterViewData
{
    public ICollection<string> Navigation { get; set; }
}

Bu ana sayfayı kullanan her görünüm, bilgilerini içeren ve ana sayfaların görünüm verilerinden türetilen güçlü bir şekilde yazılmış bir görünüm veri sınıfını alır:

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
}

Tek tek denetleyicilerin ana sayfa verilerini bir araya getirme hakkında hiçbir şey bilmesini istemediğimden, bu mantığı her denetleyiciye aktarılan bir fabrikada kapsülledim:

public interface IViewDataFactory
{
    T Create<T>()
        where T : MasterViewData, new()
}

public class ProductController : Controller
{
    public ProductController(IViewDataFactory viewDataFactory)
    ...

    public ActionResult Index()
    {
        var viewData = viewDataFactory.Create<ProductViewData>();

        viewData.Name = "My product";
        viewData.Price = 9.95;

        return View("Index", viewData);
    }
}

Miras, ilişkiyi iyi görüntülemek için ana ile eşleşir, ancak söz konusu kısmi / kullanıcı kontrolleri oluşturma söz konusu olduğunda, görünüm verilerini sayfaların görüntüleme verilerine oluşturacağım, örneğin

public class IndexViewData : MasterViewData
{
    public string Name { get; set; }
    public float Price { get; set; }
    public SubViewData SubViewData { get; set; }
}

<% Html.RenderPartial("Sub", Model.SubViewData); %>

Bu yalnızca örnek koddur ve olduğu gibi derlenmesi amaçlanmamıştır. ASP.Net MVC 1.0 için tasarlanmıştır.


4
Bu, Scott Gutherie tarafından önerilen yöntemdir, bu yüzden kabul etmem gerekir.
Simon Fox

@Simon Fox - scottgu'nun tavsiyesine bir bağlantı var mı? Bulamadım.
orip


Afedersiniz. Bunun bir kısmını anlamakta biraz güçlük çekiyorum. Denetleyicinin yapıcısına bir IViewDataFactory örneği geçirildi, ancak sistem parametresiz bir kurucu bekliyor. Arayüz için bu C # sözdizimine (özellikle "MasterViewData, new ()") da aşina değilim. Biri lütfen açıklayabilir mi veya beni iyi bir kaynağa yönlendirebilir mi? Teşekkürler.
Jason

5
Çalışmak için güçlü tipte modellere sahip olmayı seviyorum, ancak ana verileri diğer tüm modellerim ve eylemlerimle birleştirmenin büyük bir hayranı değilim. Bu iş parçacığına biraz geç geldim, ancak işleri daha gevşek tutan ana verilere yaklaşımımı yayınladım.
Todd Menier

59

Ana görünümün veriye dayalı parçalarını bölümlere ayırmayı ve Html.RenderAction kullanarak oluşturmayı tercih ediyorum . Bunun, popüler görünüm modeli miras yaklaşımına göre birkaç farklı avantajı vardır:

  1. Ana görünüm verileri, "normal" görünüm modellerinden tamamen ayrıştırılır. Bu, kalıtım yerine kompozisyondur ve değiştirilmesi daha kolay olan daha gevşek bir şekilde bağlanmış bir sistemle sonuçlanır.
  2. Ana görünüm modelleri, tamamen ayrı bir denetleyici eylemi tarafından oluşturulur. "Düzenli" eylemlerin bunun için endişelenmesine gerek yok ve zevklerime göre fazlasıyla karmaşık görünen bir veri görüntüleme fabrikasına gerek yok.
  3. Etki alanınızı görünüm modellerinizle eşlemek için AutoMapper gibi bir araç kullanırsanız, görünüm modelleriniz ana görünüm verilerini devralmadıklarında etki alanı modellerinize daha çok benzeyeceği için yapılandırmayı daha kolay bulacaksınız.
  4. Ana veriler için ayrı eylem yöntemleriyle, sayfanın belirli bölgelerine çıktı önbelleğini kolayca uygulayabilirsiniz. Tipik olarak ana görünümler, ana sayfa içeriğinden daha az sıklıkla değişen verileri içerir.

3
+1. Diğer bir avantaj, aynı görünümün geçerli çalışma zamanı durumuna bağlı olarak farklı ana sayfalar kullanmasını sağlayabilmenizdir.
StriplingWarrior

1
Bu cevabı çok beğendim - ana hatlarıyla belirtilen diğer yaklaşımlar biraz fazla karmaşık görünüyor.
Paddy

2
Bence en zarif çözüm bu.
autonomatt

1
Bu çözüm benim için de en iyi gibi görünüyor. Milyonlarca kez teşekkürler!
JimDaniel

1
Bu harika bir yoldur, ancak yine de "kısmi eylemlerinize" giden rotaları belirtmeniz gerektiğini unutmayın. Bu yanıta bakın stackoverflow.com/a/3553617/56621
Alex

20

DÜZENLE

Genel Hata aşağıda daha iyi bir cevap sağlamıştır. Lütfen onu oku!

Orijinal Cevap

Microsoft, bunun üstesinden gelmek için "resmi" yol hakkında bir girdi yayınladı . Bu, akıl yürütmelerinin bir açıklamasıyla birlikte adım adım bir gözden geçirme sağlar.

Kısacası, soyut bir denetleyici sınıfı kullanmanızı önerirler, ancak kendiniz görün.


TEŞEKKÜR EDERİM! Bu örnek TAM OLARAK yaptığım şey ... veritabanından gelen her sayfadaki kategori.
Martin

MVC'nin yazarlarından biri olan Scott Gutherie, aşağıdaki @Generic Error tarafından sağlanan çözümü öneriyor
Simon Fox

1
Sizinki resmi olarak doğru olsa ve OP tarafından cevap olarak kabul edildiğinde bile en iyi yanıta yönlendirme için +1.
IsmailS

Sizinki resmi olarak doğru olsa ve OP tarafından cevap olarak kabul edildiğinde bile en iyi yanıta yönlendirme için +1.
Dave Jellison

Aslında Todd Menier's şu anda bunun için en iyi cevap.
andreialecu

7

Soyut denetleyiciler iyi bir fikir ve daha iyi bir yol bulamadım. Başkalarının da ne yaptığını görmekle ilgileniyorum.



2

Görünüme ilettiğiniz tüm model nesneleri için ortak bir ebeveynin son derece yararlı olduğunu görüyorum.

Zaten sayfalar arasında her zaman bazı ortak model özellikleri olacaktır.


0

Request.Params nesnesi değiştirilebilir. İstek işleme döngüsünün bir parçası olarak buna skaler değerler eklemek oldukça kolaydır. Görünüm açısından bakıldığında, bu bilgi QueryString veya FORM POST'ta sağlanabilirdi. hth


0

Başka bir iyi yolun, bazı arayüzlerin ParentView gibi bazı Özellikli görünüm için Arayüz oluşturmak olabileceği konusunda, hem sayfaya referans gerektiren kontroller (ana kontrol) hem de erişilmesi gereken ana görünümler için kullanabilirsiniz. Görüntüleme.


0

Diğer çözümler zarafetten yoksundur ve çok uzun sürer. Bu çok üzücü ve fakir şeyi neredeyse bir yıl sonra yaptığım için özür dilerim:

<script runat="server" type="text/C#">
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        MasterModel = SiteMasterViewData.Get(this.Context);
    }

    protected SiteMasterViewData MasterModel;
</script>

Açıkçası, SiteMasterViewData'yı döndüren SiteMasterViewData üzerinde bu statik Get () yöntemine sahibim.


çoğu kişi için bu biraz düzensiz veya 'kirli' görünebilir, ancak işin hızlı bir şekilde yapılmasını sağlar
argh

Ugh. Html.RenderAction () kullandıysanız, kodunuzu korumak çok daha zor görünüyor.
Dan Esparza
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.