Asp.Net MVC - 无法开始监视文件更改

Posted

技术标签:

【中文标题】Asp.Net MVC - 无法开始监视文件更改【英文标题】:Asp.Net MVC - Failed to start monitoring file changes 【发布时间】:2017-11-27 23:45:26 【问题描述】:

我尝试使用 ASP.NET MVC 编写自己的 CMS,并将 html 视图存储在 DB 中。我在互联网上通过教程创建了自定义虚拟路径提供程序。

MyVirtualPathProvider 代码:

using System.Linq;
using System.Text;
using System.Web.Hosting;
using SgCms.Dal.Concrete;
using SgCms.DomainModels;

namespace SgCms.ViewFactory

    public class SgCmsVirtualPathProvider : VirtualPathProvider
    
        public override bool FileExists(string virtualPath)
        
            var view = GetViewFromDatabase(virtualPath);

            if (view == null)
            
                return base.FileExists(virtualPath);
            
            else
            
                return true;
            
        

        public override VirtualFile GetFile(string virtualPath)
        
            var view = GetViewFromDatabase(virtualPath);

            if (view == null)
            
                return base.GetFile(virtualPath);
            
            else
            
                byte[] content = ASCIIEncoding.ASCII.
                    GetBytes(view.InnerHtml);
                return new SgCmsVirtualFile
                    (virtualPath, content);
            
        

        private View GetViewFromDatabase(string virtualPath)
        
            return PageBuilder(virtualPath);
        

        private View PageBuilder(string path)
        
            var virtualPath = path.Replace("~", "");

            DataContext db = new DataContext();
            var view = from v in db.Views
                where v.Path == virtualPath
                select v;

            var res = view.SingleOrDefault();

            return res;
        
    

MyVirtualFile 代码:

using System.IO;
using System.Web.Hosting;

namespace SgCms.ViewFactory

    public class SgCmsVirtualFile : VirtualFile
    
        private byte[] viewContent;

        public SgCmsVirtualFile(string virtualPath,
            byte[] viewContent) : base(virtualPath)
        
            this.viewContent = viewContent;
        

        public override Stream Open()
        
            return new MemoryStream(viewContent);
        
    

我想通过这样的路径从数据库中获取视图:http://localhost/Module_Name/View_Name

我编写了自定义路由,现在所有请求都由一个操作处理。 甚至,当调用 GetViewFromDatabase 时,它​​会获取我想要的视图。 但是,不幸的是我有下一个例外:

目录 'c:\users\nikita litvinenko\documents\visual studio 2017\Projects\SgCms\SgCms.Web\Views\Main' 不存在。无法开始监控文件更改。 说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Web.HttpException:目录 'c:\users\nikita litvinenko\documents\visual studio 2017\Projects\SgCms\SgCms.Web\Views\Main' 不存在。无法开始监控文件更改。

来源错误:

在执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常起源和位置的信息 堆栈跟踪: [HttpException (0x80070002): 目录 'c:\users\nikita litvinenko\documents\visual studio 2017\Projects\SgCms\SgCms.Web\Views\Main' 不存在。无法开始监视文件更改。] System.Web.FileChangesMonitor.FindDirectoryMonitor(字符串目录,布尔 addIfNotFound,布尔 throwOnError)+589 System.Web.FileChangesMonitor.StartMonitoringPath(String alias, FileChangeEventHandler callback, FileAttributesData& fad) +655 System.Web.Caching.CacheDependency.Init(Boolean isPublic, String[] filenamesArg, String[] cachekeysArg, CacheDependency 依赖, DateTime utcStart) +2582 System.Web.Hosting.MapPathBasedVirtualPathProvider.GetCacheDependency(String virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) +400 System.Web.Hosting.VirtualPathProvider.GetCacheDependency(String virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) +36 System.Web.Hosting.VirtualPathProvider.GetCacheDependency(VirtualPath virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) +38 System.Web.Compilation.MemoryBuildResultCache.CacheBuildResult(String cacheKey, BuildResult result, Int64 hashCode, DateTime utcStart) +68 System.Web.Compilation.BuildManager.CacheBuildResultInternal(String cacheKey, BuildResult result, Int64 hashCode, DateTime utcStart) +70 System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath) +10180802 System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath,布尔 noBuild,布尔allowCrossApp,布尔allowBuildInPrecompile,布尔throwIfNotFound,布尔ensureIsUpToDate)+294 System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext 上下文,VirtualPath virtualPath,布尔 noBuild,布尔allowCrossApp,布尔allowBuildInPrecompile,布尔throwIfNotFound,布尔ensureIsUpToDate)+103 System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound) +165 System.Web.Compilation.BuildManager.GetCompiledType(VirtualPath virtualPath) +15 System.Web.Compilation.BuildManager.GetCompiledType(String virtualPath) +29 System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.GetCompiledType(String virtualPath) +6 System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +54 System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext 上下文)+291 System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 过滤器,Int32 filterIndex,ResultExecutingContext preContext,ControllerContext controllerContext,ActionResult actionResult)+420 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList1 filters, ActionResult actionResult) +52 System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +173 System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100 System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult 结果) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9765901 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

【问题讨论】:

那么您还需要在您的 SgCmsVirtualPathProvider 中覆盖 GetCacheDependency 方法 - 可能需要由 db 时间戳支持。 是的,它正在工作。非常感谢。 【参考方案1】:

这很容易。正如Ondrej Svejdar 所说,我应该重写我的 SgCmsVirtualPathProvider 中的 GetCacheDependency 方法。

    public override CacheDependency GetCacheDependency(
        string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart)
    
        var view = GetViewFromDatabase(virtualPath);

        if (view != null)
        
            return null;
        

        return Previous.GetCacheDependency(virtualPath,
            virtualPathDependencies, utcStart);
    

【讨论】:

【参考方案2】:

为什么不使用文件而不是在流中返回响应?

wath this

【讨论】:

以上是关于Asp.Net MVC - 无法开始监视文件更改的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Visual Studio ASP.NET Core 监视文件更改“dotnet watch”

无法更改 ASP.NET MVC 3 中文本框的值

初识ASP.NET MVC

ASP.NET MVC使用Bootstrap系列——开始使用Bootstrap

ASP.NET MVC 页面无法加载并显示“找不到资源”

加载配置文件时出错:无法开始监视对 '\\share' 的更改