Я пишу IFileProvider
, с помощью которого я намерен загружать контент из базы данных.Я адаптировал этот код ниже, и в качестве подтверждения концепции я просто жестко кодирую строку, если конкретный запрос соответствует «контакту».
На диске у меня есть файл, contact.cshtml
в моей папке Страницы.Если я не использую мой новый DatabaseFileProvider
, то страница contact.cshtml
отрисовывается идеально, как и ожидалось.
Когда я включаю IFileProvider
ниже, запрос к contact.cshtml
страница действительно переопределяется - опять же, как и ожидалось.
Однако, если попытаться перехватить запрос на файл cshtml, который не существует, мой код фактически никогда не попадет.Например, вы можете видеть в моих комментариях, что если я заменю работу «контакт» на «динамическую», она не будет выполнена.
Я уверен, что это связано с тем, как я переплел мою 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
, но проблема остается.Я также изменил порядок провайдеров вокруг.
Я уверен, что делаю что-то глупое - кто-то может указать мне правильное направление?Очень ценится.