MVC: VirtualPathProvider

本文关键字:VirtualPathProvider MVC | 更新日期: 2023-09-27 18:20:48

我已经在SO上搜索过了,但我没有找到解决方案,所以希望你们中的某个人能为我提供一些指导。

我希望MVC从数据库加载视图,因此我创建了一个VirtualFile和一个VirtualPathProvider。

这是来自VirtualFile:的代码

public class OxygenVirtualFile : VirtualFile
{
    #region Constructors
    /// <summary>
    ///     Create a new instance of the <see cref="OxygenVirtualFile"/>.
    /// </summary>
    /// <param name="virtualPath">The virtual path to the resource represented by this instance.</param>
    /// <param name="body">The contents of the virtual file.</param>
    public OxygenVirtualFile(string virtualPath, string body)
        : base(virtualPath)
    {
        content = body;
    }
    #endregion
    #region Properties
    /// <summary>
    ///     Gets the contents of the virtual file.
    /// </summary>
    private readonly string content;
    /// <summary>
    ///     A boolean that indicates wether this virtual file does exists.
    /// </summary>
    public bool Exists
    {
        get { return (content != null); }
    }
    #endregion
    #region VirtualFile Members
    /// <summary>
    ///     returns a read-only stream to the virtual resource.
    /// </summary>
    /// <returns>A read-only stream to the virtual resource.</returns>
    public override Stream Open()
    {
        var encoding = new ASCIIEncoding();
        return new MemoryStream(encoding.GetBytes(content), false);
    }
    #endregion
}

然后我有了提供者本身:

public class OxygenVirtualPathProvider : VirtualPathProvider
{
    #region Constructors
    /// <summary>
    ///     Create a new instance of the <see cref="OxygenVirtualPathProvider"/>.
    /// </summary>
    /// <param name="exludedPath">The path that should be excluded and thus not be rendered using this virtual path provider.</param>
    /// <remarks>
    ///     If the specified path does occur somewhere in the url, the view is not rendered using this <see cref="VirtualPathProvider"/>.
    ///     In all the other cases, the view is rendered using this <see cref="VirtualPathProvider"/>.
    /// </remarks>
    public OxygenVirtualPathProvider(string exludedPath)
    {
        var unityContainer = DependencyResolver.Current.GetService<IUnityContainer>();
        unitOfWork = unityContainer.Resolve<IUnitOfWork>();
        this.exludedPath = exludedPath;
    }
    #endregion
    #region Properties
    /// <summary>
    ///     Gets the <see cref="IUnitOfWork"/> which is used to access the database.
    /// </summary>
    private readonly IUnitOfWork unitOfWork;
    /// <summary>
    ///     Get the root path of the dynamic views.
    /// </summary>
    private readonly string exludedPath;
    #endregion
    #region Methods
    /// <summary>
    ///     Check if the view is dynamic view.
    /// </summary>
    /// <param name="virtualPath">The path of the virtual view.</param>
    /// <returns>True is the view is a dynamic view, false otherwise.</returns>
    public bool IsDynamicView(string virtualPath)
    {
        // If the path which is requested does contain an excluded url, this virtual path provider will not handle this.
        if (virtualPath.ToLower().Contains(exludedPath))
        { return false; }
        var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(virtualPath);
        var viewExists = DoesViewExistInDataBase(fileNameWithoutExtension);
        return viewExists && !virtualPath.ToLower().Contains(exludedPath);
    }
    /// <summary>
    ///     Verify that the requested view exists in the database.
    /// </summary>
    /// <param name="virtualPath">The path of the virtual view.</param>
    /// <returns>True if the view exists in the database, false otherwise.</returns>
    public bool DoesViewExistInDataBase(string virtualPath)
    {
        var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(virtualPath);
        return new ViewManager(unitOfWork).Exists(fileNameWithoutExtension);
    }
    /// <summary>
    ///     Gets the view from the database.
    /// </summary>
    /// <param name="virtualPath">The virtual path of the view to retrieve.</param>
    /// <returns>A string representing the body of the view.</returns>
    public String GetViewBodyFromDb(string virtualPath)
    {
        var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(virtualPath);
        return new ViewManager(unitOfWork).Get(fileNameWithoutExtension);
    }
    #endregion
    #region VirtualPathProvider Members
    /// <summary>
    ///     Gets a value that indicates whether a file exists in the virtual file system.
    /// </summary>
    /// <param name="virtualPath">The path to the virtual file.</param>
    /// <returns>true if the file exists in the virtual file system; otherwise, false.</returns>
    public override bool FileExists(string virtualPath)
    {
        return IsDynamicView(virtualPath) || base.FileExists(virtualPath);
    }
    /// <summary>
    ///     Gets a virtual file from the virtual file system.
    /// </summary>
    /// <param name="virtualPath">The path to the virtual file.</param>
    /// <returns>A descendent of the <see cref="VirtualFile"/> class that represents a file in the virtual file system.</returns>
    public override VirtualFile GetFile(string virtualPath)
    {
        return IsDynamicView(virtualPath) ? new OxygenVirtualFile(virtualPath, GetViewBodyFromDb(virtualPath)) : base.GetFile(virtualPath);
    }
    /// <summary>
    ///     Returns a hash of the specified virtual paths.
    /// </summary>
    /// <param name="virtualPath">The path to the primary virtual resource.</param>
    /// <param name="virtualPathDependencies">An array of paths to other virtual resources required by the primary virtual resource.</param>
    /// <returns>A hash of the specified virtual paths.</returns>
    public override string GetFileHash(string virtualPath, System.Collections.IEnumerable virtualPathDependencies)
    {
        return base.GetFileHash(virtualPath, virtualPathDependencies);
    }
    /// <summary>
    ///     Creates a cache dependency based on the specified virtual paths.
    /// </summary>
    /// <param name="virtualPath">The path to the primary virtual resource.</param>
    /// <param name="virtualPathDependencies">An array of paths to other resources required by the primary virtual resource.</param>
    /// <param name="utcStart">The UTC time at which the virtual resources were read.</param>
    /// <returns>A <see cref="CacheDependency"/> object for the specified virtual resources.</returns>
    public override CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
    {
        return Previous.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
    }
    #endregion
}

为了确保我的视图正确继承,我确实返回了这个:

 public string Get(string name)
 {
     return "@inherits System.Web.Mvc.WebViewPage<dynamic>" +
            " <h2>title</h2>";
 }

根据我和我在SO上发现的,这应该是可行的,但会抛出以下错误:

The view at '~/Views/Home/articles.aspx' must derive from ViewPage, ViewPage<TModel>, ViewUserControl, or ViewUserControl<TModel>.

编辑:

提供者也在global.asax文件中注册:

protected void Application_Start()
{
    HostingEnvironment.RegisterVirtualPathProvider(new OxygenVirtualPathProvider("/CMS/"));
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
}

有人知道这件事吗?

MVC: VirtualPathProvider

好的,

我设法找到了解决办法。Mvc搜索了ASPX、ASCX、CSHTML和其他文件。

当我将VirtualPathProvider更改为仅在搜索的文件以.CSHTML结尾时加载动态文件时,错误消失了。

它现在起作用了,但我想知道我为什么会有这种行为。有谁能给我一个答案吗?

相关文章:
  • 没有找到相关文章