【发布时间】:2018-11-19 04:16:15
【问题描述】:
我正在写一个IFileProvider,我打算用它从数据库中加载内容。我在下面修改了这段代码,作为概念验证,如果特定请求与“联系人”匹配,我只是对字符串进行硬编码。
在磁盘上,我的 Pages 文件夹中有一个文件 contact.cshtml。如果我不使用我的新DatabaseFileProvider,那么contact.cshtml 页面将按预期完美呈现。
当我在下面包含 IFileProvider 时,对 contact.cshtml 页面的请求确实被覆盖了 - 再次,正如预期的那样。
但是,如果尝试拦截对 不存在 的 cshtml 文件的请求,我的代码实际上永远不会被命中。例如,您可以在我的 cmets 中看到,如果我将工作“联系人”替换为“动态”,则无法执行。
我确定这与我将 IFileProvider 与 MVC 的默认 PhysicalFileProvider 交织在一起的方式有关。
这是我的设置:
public class DatabaseFileProvider : IFileProvider
{
public IFileInfo GetFileInfo(string subpath)
{
var result = new DatabaseFileInfo(subpath);
return result.Exists ? result as IFileInfo : new NotFoundFileInfo(subpath);
}
}
public class DatabaseFileInfo : IFileInfo
{
private string _viewPath;
private byte[] _viewContent;
private DateTimeOffset _lastModified;
private bool _exists = false;
public DatabaseFileInfo(string viewPath)
{
_viewPath = viewPath;
GetView(viewPath);
}
public bool Exists => _exists;
public bool IsDirectory => false;
public DateTimeOffset LastModified => _lastModified;
public long Length
{
get
{
using (var stream = new MemoryStream(_viewContent))
{
return stream.Length;
}
}
}
public string Name => Path.GetFileName(_viewPath);
public string PhysicalPath => null;
public Stream CreateReadStream()
{
return new MemoryStream(_viewContent);
}
private void GetView(string viewPath)
{
if (viewPath == null) return;
if (viewPath.ToLower().IndexOf("_view") != -1) return;
// PROBLEM: this only works if the file EXISTS on disk ???!!! Try switching out "contact" (works) with "dynamic" (doesn't work)
// Not even the breakpoint gets hit?
if (viewPath.ToLower().ToLower().IndexOf("contact") == -1) return;
var html = "This is NOT cshtml";
_viewContent = Encoding.UTF8.GetBytes(html);
_lastModified = DateTime.Now;
_exists = true;
}
}
...在我的Startup.cs 文件中:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<RazorViewEngineOptions>(opts => {
opts.FileProviders.Clear();
opts.FileProviders.Add(new DatabaseFileProvider());
opts.FileProviders.Add(Environment.ContentRootFileProvider);
/*
opts.FileProviders.Clear();
opts.FileProviders.Add(new CompositeFileProvider(
Environment.ContentRootFileProvider,
new DatabaseFileProvider()
));
*/
}
);
}
如您所见,我使用CompositeFileProvider 进行了第二个实现,但问题仍然存在。我也改变了供应商的顺序。
我确定我在做一些愚蠢的事情 - 有人能指出我正确的方向吗?
【问题讨论】:
标签: asp.net-core asp.net-core-mvc