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

时间:2017-06-24 14:50:24

标签: c# asp.net-mvc

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

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);
        }
    }
}

我希望通过这样的路径从DB获取视图: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:Directory' c:\ users \ nikita litvinenko \ documents \ visual studio 2017 \ Projects \ SgCms \ SgCms.Web \ Views \ Main'不存在。无法开始监控文件更改。

     

来源错误:

     

在执行当前Web请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常的起源和位置的信息   堆栈跟踪:       [HttpException(0x80070002):目录&#39; c:\ users \ nikita litvinenko \ documents \ visual studio 2017 \ Projects \ SgCms \ SgCms.Web \ Views \ Main&#39;不存在。无法开始监控文件更改。]          System.Web.FileChangesMonitor.FindDirectoryMonitor(String dir,Boolean addIfNotFound,Boolean throwOnError)+589          System.Web.FileChangesMonitor.StartMonitoringPath(String alias,FileChangeEventHandler callback,FileAttributesData&amp; fad)+655          System.Web.Caching.CacheDependency.Init(Boolean isPublic,String [] filenamesArg,String [] cachekeysArg,CacheDependency dependency,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,Boolean noBuild,Boolean allowCrossApp,Boolean allowBuildInPrecompile,Boolean throwIfNotFound,Boolean ensureIsUpToDate)+294          System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context,VirtualPath virtualPath,Boolean noBuild,Boolean allowCrossApp,Boolean allowBuildInPrecompile,Boolean throwIfNotFound,Boolean 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 context)+291          System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext,ActionResult actionResult)+13          System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList 1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +56 System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList 1个过滤器,Int32 filterIndex,ResultExecutingContext preContext,ControllerContext controllerContext,ActionResult actionResult)+420          System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext,IList 1 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.WrappedAsyncResult 1.CallEndDelegate(IAsyncResult asyncResult)+10          System.Web.Mvc.Async.WrappedAsyncResultBase 1.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.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult)+29          System.Web.Mvc.Async.WrappedAsyncResultBase 1.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.WrappedAsyncVoid 1.CallEndDelegate(IAsyncResult asyncResult)+22          System.Web.Mvc.Async.WrappedAsyncResultBase 1.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.WrappedAsyncVoid 1.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 result)+9          System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+ 9765901          System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+155

2 个答案:

答案 0 :(得分:2)

这很简单。如上所述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);
    }

答案 1 :(得分:0)

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

wath this