2017-12-22 163 views
5

Tüm web uygulama sayfalarında gösterilen dinamik menü (DB'de depolanmış) yapmaya çalışıyorum. Google'ı Kullanma Menü görünümünü Master View'ın (_Layout.cshtml) bir parçası olarak yapmak daha iyi olduğunu buldum. Ve bundan dolayı, denetleyicinin her eylemi yöntemi menü modeliyle veri içermelidir. olanakları bekliyor/Kurucu denetleyicisinde MVC async yöntemi

Ayrıca https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/views/passing-data-to-view-master-pages-cs

, ben asenk kullanmaya çalışıyorum ve benim PageService (menü) ToListAsync kullanıyor: Kod tekrarını önlemek için onun yapıcı kullanarak veri taban denetleyicisi oluşturmak ve sunmak için çözüm buldu() DB'den veri almak için. Yani şimdi ben BaseController yapıcı bir zaman uyumsuz yöntemini sahip olduğunu, bir sorun var:

public class BaseController : AsyncController, IBaseController 
{ 
    private readonly IPageService _pageService; 

    public BaseController(IPageService pageService) 
    { 
     _pageService = pageService; 
     SetBaseViewModelAsync(); 
    } 

    private async Task SetBaseViewModelAsync() 
    { 
     ViewData["Pages"] = await _pageService.GetAllAsync(); 
    } 
} 

Bu KÖTÜ KOD olduğunu biliyorum, ama düzgün bu durumu nasıl tasarlanacağı bilmiyorum. Belki de dinamik menüyü veya senkronize olmayan bir şekilde veri elde etmenin bir başka yolunu oluşturmanın daha iyi bir yolu var mı?

Ayrıca, bu makale buldum ama bilmiyorum çünkü onun çözüm uygulayabilirler eğer kontrolör örneği oluşturma işleyebilir eğer bilmiyorum:

http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html

+0

Bu kötü tasarım, orada haklısınız. Bunun yerine –

+0

yerine bir orta eşya veya eylem filtresine bakmalısınız. Lütfen uygun tasarımlara sahip makalelere bazı bağlantılar sunabilir misiniz? Çünkü dinamik menüyü nasıl uygulayacağımı bulmak için 1-2 saat çalıştım. –

+2

Bu, [Çocuk Eylemi] için iyi bir aday gibi görünüyor (https://stackoverflow.com/questions/12530016/what-is-an-mvc-child-action). Ayrıca bu soruya https: // stackoverflow bakın.com/questions/21948909/asp-net-mvc-controller-for-layout – Jasen

cevap

6

yerine her şeyi kaynaklanan

[ChildActionOnly] 
public Default() 
{ 
    var viewModel = _pageService.GetAllAsync(); 
    return Partial(viewModel); 
} 
: sadece Default adlı bir yöntem oluşturmak, MenuController denilen bir denetleyici oluşturup ardından Layout'tan diyebilirsin (ekstra çalışma ve test bir sürü olabilir) bir ana kontrolöre gelen Planınıza 10 girin:

@{Html.RenderAction("Default", "Menu");} 

Bu gerçekten en kolay ve en temiz çözümdür. En büyük PRO, menü için önbelleği, yöntem çağrısından ayrı olarak kontrol edebilmenizdir. Bu moda Async kodu çalıştırmak için asp.net-mvc (1-5) için iyi bir çözüm yoktur. (ActionFilters can't be async ve (Render) Partials zaman uyumsuz olamaz. Hala bu sadece Sync çalışır, bir zaman uyumsuz yöntemini çağırabilirsiniz.

Render vs Non-Render Performance.

+0

Yanıt için teşekkürler! MVC'ye yeni geldim, bu yüzden RenderAction hakkında bir şeyler okuyacağım ve çözümünüzü deneyeceğim. Ayrıca, önbellek olasılığı burada harika! –

+0

Çözümünüz uygulandı ancak bazı nüansları var: Çocuk eylemleri async olamaz: https://stackoverflow.com/questions/24072720/async-partialview-causes-httpserverutility-execute-blocked-exception/47962963#47962963 Bu yüzden eylemi ChildAction olarak yapmaya karar verdim. Sadece çocuk yapmak gerekli mi? Ayrıca cevabınızı da değiştirebilir misiniz, bu yüzden kabul uygun olur mu? Örneğin, örneğiniz ChildAction –

+0

'daki uyumsuz koda sahip olduğundan, Async kodunda anahtar kelimeler bulunmuyor. Benimki bu anahtar kelimeleri kullanmaz. Bir uyarı ile derlemesi gerekir. Aksi takdirde sadece [bir senkronizasyon yönteminde uyumsuzluk kodu] arayabilirsiniz (https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c/25097498#25097498) . –

-1

Ben, benim görünümünde Html.RenderAction çağrı yapma işlevini değiştirdi

@{ 
    Html.RenderAction("Index", "Pages"); 
} 

ve denetleyici: Erik Philips önerdi

public class PagesController : AsyncController, IPagesController 
{ 
    private readonly IPagesService _pagesService; 

    public PagesController(IPagesService pagesService) 
    { 
     _pagesService = pagesService; 
    } 

    [HttpGet] 
    [Route("")] 
    public async Task<ActionResult> IndexAsync() 
    { 
     var viewModel = await _pagesService.GetAllAsync(); 
     return PartialView("MenuPartial", viewModel); 
    } 
} 

Ama RenderAction zaman uyumsuz denetleyici Eylemler çalışmaz:senkron çağrı burada mümkün tek gibi

Async PartialView causes "HttpServerUtility.Execute blocked..." exception

Yani görünüyor.

İlgili konular