如何从控制器告诉 ASP.NET Core 视图存在?
Posted
技术标签:
【中文标题】如何从控制器告诉 ASP.NET Core 视图存在?【英文标题】:How to tell ASP.NET Core view exists from controller? 【发布时间】:2016-10-07 20:26:14 【问题描述】:有时控制器需要检查视图是否存在,以便在不存在时采取一些措施?
我已经看到过类似Does a view exist in ASP.NET MVC? 的类似问题,用于之前版本的 asp.net mvc,但此类方法不适用于 ASP.NET Core。我一直无法从控制器内部找到有关如何使用 ASP.NET Core 执行此操作的任何文档。
鉴于以下情况:
string viewLoc= "~/views/some-folder/some-file.cshtml";
控制器如何判断视图是否存在?
【问题讨论】:
【参考方案1】:这就是我在 Asp.Net Core 1.0 中解决这个问题的方法。使用 ICompositeViewEngine。下面是一个例子。
private readonly ICompositeViewEngine _compositeViewEngine;
public YourController(ICompositeViewEngine compositeViewEngine)
_compositeViewEngine = compositeViewEngine;
然后在你的行动中:
[Route("/location/name")]
public IActionResult Location(string name)
var viewName = $"~/Views/Location/name.cshtml";
var result = _compositeViewEngine.GetView("", viewName, false);
if (result.Success) return View(viewName);
// or do whatever you want
return NotFound();
【讨论】:
这个答案应该是从 Asp.Net Core 3.0 开始的公认答案,其中预编译视图是默认的。虽然File.Exists
检查仍然可以在 dev 中工作,但一旦网站发布,视图将不存在,因此即使视图作为预编译视图存在,File.Exists
也会失败。 compositeViewEngine.GetView
将看到预编译视图(如果存在)。【参考方案2】:
在我看来,当 View 在运行时不存在时,这是一个糟糕的设计 - 但我可能不理解这种情况。
但是回答您的问题: 我不知道有什么具体的方法可以做到这一点,但是...... View 是一个文件,所以你可以检查文件是否存在于磁盘上?
例如:
System.IO.File.Exists(@"Views\Home\Index.cshtml");
System.IO.File.Exists(@".\Views\Home\Index.cshtml");
在这种情况下不要使用~
,只使用Views\
或.\Views\
【讨论】:
我也想出了一个类似的方法,但使用了通过附加IHostingEnvironment
ContentRootPath
实现的绝对路径,但我觉得有点脏,因为我可以看到我可以注入@ 987654329@ 进入控制器,它有一个FindView
方法。但我永远无法将ViewEngineResult.Success
视为真实。所以最后我确实求助于使用 System.IO.FIle.Exists。
请注意 IApplicationEnvironment
和 IRuntimeEnvironment
在 RC2 中已被删除,可通过 Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default
静态访问,更多信息:github.com/aspnet/PlatformAbstractions/issues/37
好提示。就我而言,我使用IHostingEnvironment
来获取ContentRootPath
。 IHostingEnvironment
是 Controller
可在 RC2 中注入。
a...抱歉,我读得太快了...IHostingEnvironment
和IApplicationEnvironment
不一样;)
如果视图被预编译并且文件在磁盘上不存在,则会中断。以上是关于如何从控制器告诉 ASP.NET Core 视图存在?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的 ASP.NET Core 3.1 控制器会自动为从视图返回的 EF Core 模型分配 ID?
如何将位于应用程序部分 (DLL) 中的部分视图呈现到主 asp.net core 2.2 项目中