뷰를 렌더링하기 전에 컨트롤러 내에서 특정 뷰 이름이 있는지 확인할 수 있습니까?
렌더링 할 뷰의 이름을 동적으로 결정해야합니다. 해당 이름의 뷰가 있으면 해당 뷰를 렌더링해야합니다. 사용자 정의 이름으로보기가 없으면 기본보기를 렌더링해야합니다.
컨트롤러 내에서 다음 코드와 유사한 작업을 수행하고 싶습니다.
public ActionResult Index()
{
var name = SomeMethodToGetViewName();
// The 'ViewExists' method is what I've been unable to find.
if (ViewExists(name))
{
retun View(name);
}
else
{
return View();
}
}
답변
private bool ViewExists(string name)
{
ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null);
return (result.View != null);
}
복사 / 붙여 넣기 확장 방법을 찾는 사람들을 위해 :
public static class ControllerExtensions
{
public static bool ViewExists(this Controller controller, string name)
{
ViewEngineResult result = ViewEngines.Engines.FindView(controller.ControllerContext, name, null);
return (result.View != null);
}
}
답변
하나의 뷰 엔진 만 사용한다고 가정하고 다음과 같은 것을 시도하는 것은 어떻습니까?
bool viewExists = ViewEngines.Engines[0].FindView(ControllerContext, "ViewName", "MasterName", false) != null;
답변
[반드시 권장되는 것은 아님] 또 다른 방법이 있습니다.
try
{
@Html.Partial("Category/SearchPanel/" + Model.CategoryKey)
}
catch (InvalidOperationException) { }
답변
Dave가 제공 한 솔루션을 기반으로 여러 컨트롤러 조치에서이를 재사용하려면 다음과 같이 사용자 정의보기 결과를 정의 할 수 있습니다.
public class CustomViewResult : ViewResult
{
protected override ViewEngineResult FindView(ControllerContext context)
{
string name = SomeMethodToGetViewName();
ViewEngineResult result = ViewEngines.Engines.FindView(context, name, null);
if (result.View != null)
{
return result;
}
return base.FindView(context);
}
...
}
그런 다음 작업에서 사용자 정의보기의 인스턴스를 반환하면됩니다.
public ActionResult Index()
{
return new CustomViewResult();
}
답변
ViewEngines.Engines.FindView(ViewContext.Controller.ControllerContext, "View Name").View != null
내 2 센트.
답변
asp.net core 2.x에서는 ViewEngines
속성이 더 이상 존재하지 않으므로 ICompositeViewEngine
서비스 를 사용해야합니다 . 이것은 종속성 주입을 사용하여 허용되는 답변의 변형입니다.
public class DemoController : Controller
{
private readonly IViewEngine _viewEngine;
public DemoController(ICompositeViewEngine viewEngine)
{
_viewEngine = viewEngine;
}
private bool ViewExists(string name)
{
ViewEngineResult viewEngineResult = _viewEngine.FindView(ControllerContext, name, true);
return viewEngineResult?.View != null;
}
public ActionResult Index() ...
}
궁금한 점 : 기본 인터페이스 IViewEngine
는 서비스로 등록되지 않았으므로 ICompositeViewEngine
대신 삽입해야합니다 . 그러나 FindView()
메서드는에 의해 제공 IViewEngine
되므로 멤버 변수가 기본 인터페이스를 사용할 수 있습니다.
답변
다음은 Core 2.2 용 Razor에서 수행하는 방법입니다. 호출은 “Find View”가 아니라 “GetView”입니다.
@using Microsoft.AspNetCore.Mvc.ViewEngines
@inject ICompositeViewEngine Engine
...
@if (Engine.GetView(scriptName, scriptName, isMainPage: false).Success)
{
@await Html.PartialAsync(scriptName)
}