ASP.NET MVC中是否存在视图?

And*_*son 93 asp.net-mvc

在渲染视图之前,是否可以确定控制器中是否存在特定视图名称?

我需要动态确定要呈现的视图的名称.如果存在具有该名称的视图,那么我需要呈现该视图.如果自定义名称没有视图,那么我需要渲染默认视图.

我想在我的控制器中执行类似于以下代码的操作:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ray 149

 private bool ViewExists(string name)
 {
     ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null);
     return (result.View != null);
 }
Run Code Online (Sandbox Code Playgroud)

对于那些寻找复制/粘贴扩展方法的人:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这可能更好.我不知道ViewEngines集合本身有一个FindView方法. (2认同)

Lan*_*per 18

假设您只使用一个视图引擎,尝试类似下面的内容:

bool viewExists = ViewEngines.Engines[0].FindView(ControllerContext, "ViewName", "MasterName", false) != null;
Run Code Online (Sandbox Code Playgroud)


Sim*_*ver 8

这是另一种[不一定推荐]的方式

 try
 {
     @Html.Partial("Category/SearchPanel/" + Model.CategoryKey)
 }
 catch (InvalidOperationException) { }
Run Code Online (Sandbox Code Playgroud)

  • 这实际上是我的用途,因为我正在寻找一种方法来使用特定于文化的局部视图.所以我只用文化特定的视图名称调用它,然后调用catch中的默认视图.我在实用程序函数中执行此操作,因此我无法访问`ControllerContext`,因为`FindView`方法需要. (2认同)

idi*_*lov 5

在asp.net core 2.x和aspnet6中,该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() ...
}
Run Code Online (Sandbox Code Playgroud)

出于好奇:基本接口IViewEngine没有注册为服务,因此我们必须注入ICompositeViewEngine。然而,该FindView()方法是由 提供的,IViewEngine因此成员变量可以使用基本接口。