2017-12-22 29 views
5

모든 웹 응용 프로그램 페이지에 표시되는 동적 메뉴 (DB에 저장)를 만들려고합니다. Google을 사용하여 메뉴보기를 마스터보기 (_Layout.cshtml)의 일부로 만드는 것이 좋습니다. 이 때문에 컨트롤러의 모든 동작 메소드에는 메뉴 모델이있는 데이터가 있어야합니다. 가능성을 기다리고 있습니다/생성자 컨트롤러에서 MVC 비동기 메서드

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

, 내가 비동기를 사용하기 위해 노력하고있어 내 PageService (메뉴) ToListAsync을 사용하고 있습니다 : 코드 중복을 피하기 위해 나는 그것의 생성자를 사용하여 데이터를 기본 컨트롤러를 만들고 제공하는 솔루션을 발견()를 사용하여 DB에서 데이터를 가져옵니다. 그래서 지금은 BaseController 생성자가 비동기 방법이 있는지, 문제가 :

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

나는이 나쁜 코드 것을 알고,하지만 난 제대로이 상황을 설계하는 방법을 모르겠어요. 어쩌면 동적 메뉴를 만들거나 데이터를 비동기 적으로 가져 오는 다른 방법을 만드는 더 좋은 방법이 있을까요?

또한, 나는이 기사를 찾았지만, 내가 알고하지 않기 때문에 나는 그것의 솔루션을 적용 할 수 있을지는 컨트롤러 인스턴스 생성 처리 할 수 ​​있을지 모르겠어요 :

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

+0

그건 나쁜 디자인이야, 거기 맞습니다. 대신 미들웨어 또는 액션 필터를 찾아야합니다. –

+0

응답 해 주셔서 감사합니다! 적절한 디자인의 기사에 대한 링크를 제공해주십시오. 동적 메뉴를 구현하는 방법을 찾기 위해 1-2 시간 동안 봤 거든. –

+2

[Child Action] (https://stackoverflow.com/questions/12530016/what-is-an-mvc-child-action)의 후보로 들립니다. 이 질문은 https : // stackoverflow를 참조하십시오.com/questions/21948909/asp-net-mvc-controller-for-layout – Jasen

답변

6

대신 모든 것을 유도를

[ChildActionOnly] 
public Default() 
{ 
    var viewModel = _pageService.GetAllAsync(); 
    return Partial(viewModel); 
} 
: 당신은 단지 Default라는 메소드를 작성, MenuController라는 컨트롤러를 생성 한 다음 레이아웃에서 호출 할 수 있습니다 (추가 작업 및 테스트를 많이 할 수 있습니다) 기본 컨트롤러에서 레이아웃에서 10 :

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

이것은 실제로 가장 쉽고 깨끗한 해결책입니다. 가장 큰 PRO는 메서드 호출과는 별도로 메뉴의 캐시를 제어 할 수 있다는 것입니다. Asp.net-mvc (1-5)가 비동기 코드를 실행하는 좋은 방법은 없습니다. (ActionFilters can't be async 및 (렌더링) 파셜는 비동기가 될 수 없습니다. 당신은 여전히 ​​그냥 동기화를 실행, 비동기 메서드를 호출 할 수 있습니다.

Render vs Non-Render Performance.

+0

응답 해 주셔서 감사합니다! MVC를 처음 사용하기 때문에 RenderAction에 대해 읽고 솔루션을 사용해 보겠습니다. 또한, 여기 캐시 가능성이 좋습니다! –

+0

솔루션을 적용했지만 약간의 차이가 있습니다. 하위 작업을 비동기로 설정할 수 없습니다. https://stackoverflow.com/questions/24072720/async-partialview-causes-httpserverutility-execute-blocked-exception/47962963#47962963 그래서 나는 ChildAction으로 그 행동을하지 않기로 결정했습니다. 아이만을 키울 필요가 있습니까? 답변을 수정해도 수용이 적절합니까? 이제 예제에 ChildAction에 비동기 코드가 있기 때문에 –

+0

비동기 코드에 async/await keywords가 있습니다. 광산에서는 이러한 키워드를 사용하지 않습니다. 경고와 함께 컴파일해야합니다. 그렇지 않으면 [sync 메소드 내에서 비동기 코드를 호출 할 수 있습니다.] (https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c/25097498#25097498) . –

-1

나는대로, 내보기에 Html.RenderAction를 호출하는 기능을 변경

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

및 컨트롤러 : 에릭 필립스는 제안

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

그러나 RenderAction 비동기 컨트롤러 작업 작동하지 않습니다 : 0123을 동기 호출이 여기에 수있는 유일한 사람처럼

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

그래서 보인다.