Прерывистая проблема пути просмотра с пользовательским механизмом просмотра бритвы MVC

У нас есть приложение Sass, в котором мы только что реализовали пользовательский механизм просмотра бритвы, чтобы позволить нам обслуживать различные виды в зависимости от текущего пользователя, который вошел в систему. В Dev это все работало нормально. Однако в Production (общий веб-хостинг) у нас периодически возникают проблемы с попыткой обслужить несуществующее представление, используя неправильный путь представления.

Что происходит, так это то, что после развертывания все работает нормально. Затем примерно через 20 - 30 минут мы начинаем получать просмотр не найденных ошибок. Если я изменю файл web.conf для принудительного перезапуска пула приложений, то все снова будет работать нормально... какое-то время.

Похоже, что в некоторых случаях метод FileExists возвращает истину для этих путей. Не уверен, что это связано с проблемой кэширования или с общим хостом, веб-фермой, несколькими запросами на одну и ту же страницу в одно и то же время, когда результаты FileExists пересекаются и т. Д.??? Я понятия не имею.

Ошибка:

System.Web.HttpException: The file '/Areas/OrderMgmt/Views/HH/ManageOrders/Pickup.cshtml' does not exist.

В приведенном выше случае это представление не существует, оно находится в папке _Base: /Areas/OrderMgmt/Views/HH/ManageOrders/Pickup.cshtml

Ниже приведен код пользовательского представления:

{
//http://lonetechie.com/2012/09/25/multi-tenant-architecture-with-asp-net-mvc-4/
public class MulitTenantRazorViewEngine : RazorViewEngine
{
    public const string baseFolderPath = "_Base";

    public MulitTenantRazorViewEngine()
    {
        _logger = LogManager.GetLogger(GetType());

        AreaViewLocationFormats = new[] {
        "~/Areas/{2}/Views/%1/{1}/{0}.cshtml",
        "~/Areas/{2}/Views/%1/{1}/{0}.vbhtml",
        "~/Areas/{2}/Views/%1/Shared/{0}.cshtml",
        "~/Areas/{2}/Views/%1/Shared/{0}.vbhtml",
        "~/Areas/{2}/Views/_Base/{1}/{0}.cshtml",
        "~/Areas/{2}/Views/_Base/{1}/{0}.vbhtml",
        "~/Areas/{2}/Views/_Base/Shared/{0}.cshtml",
        "~/Areas/{2}/Views/_Base/Shared/{0}.vbhtml"
        };

        AreaMasterLocationFormats = new[] {
        "~/Areas/{2}/Views/%1/{1}/{0}.cshtml",
        "~/Areas/{2}/Views/%1/{1}/{0}.vbhtml",
        "~/Areas/{2}/Views/%1/Shared/{0}.cshtml",
        "~/Areas/{2}/Views/%1/Shared/{0}.vbhtml",
        "~/Areas/{2}/Views/_Base/{1}/{0}.cshtml",
        "~/Areas/{2}/Views/_Base/{1}/{0}.vbhtml",
        "~/Areas/{2}/Views/_Base/Shared/{0}.cshtml",
        "~/Areas/{2}/Views/_Base/Shared/{0}.vbhtml"
        };

        AreaPartialViewLocationFormats = new[] {
        "~/Areas/{2}/Views/%1/{1}/{0}.cshtml",
        "~/Areas/{2}/Views/%1/{1}/{0}.vbhtml",
        "~/Areas/{2}/Views/%1/Shared/{0}.cshtml",
        "~/Areas/{2}/Views/%1/Shared/{0}.vbhtml",
        "~/Areas/{2}/Views/_Base/{1}/{0}.cshtml",
        "~/Areas/{2}/Views/_Base/{1}/{0}.vbhtml",
        "~/Areas/{2}/Views/_Base/Shared/{0}.cshtml",
        "~/Areas/{2}/Views/_Base/Shared/{0}.vbhtml"
        };

        ViewLocationFormats = new[] {
        "~/Views/%1/{1}/{0}.cshtml",
        "~/Views/%1/{1}/{0}.vbhtml",
        "~/Views/%1/Shared/{0}.cshtml",
        "~/Views/%1/Shared/{0}.vbhtml",
        "~/Views/_Base/{1}/{0}.cshtml",
        "~/Views/_Base/{1}/{0}.vbhtml",
        "~/Views/_Base/Shared/{0}.cshtml",
        "~/Views/_Base/Shared/{0}.vbhtml"
        };

        MasterLocationFormats = new[] {
        "~/Views/%1/{1}/{0}.cshtml",
        "~/Views/%1/{1}/{0}.vbhtml",
        "~/Views/%1/Shared/{0}.cshtml",
        "~/Views/%1/Shared/{0}.vbhtml",
        "~/Views/_Base/{1}/{0}.cshtml",
        "~/Views/_Base/{1}/{0}.vbhtml",
        "~/Views/_Base/Shared/{0}.cshtml",
        "~/Views/_Base/Shared/{0}.vbhtml"
        };

        PartialViewLocationFormats = new[] {
        "~/Views/%1/{1}/{0}.cshtml",
        "~/Views/%1/{1}/{0}.vbhtml",
        "~/Views/%1/Shared/{0}.cshtml",
        "~/Views/%1/Shared/{0}.vbhtml",
        "~/Views/_Base/{1}/{0}.cshtml",
        "~/Views/_Base/{1}/{0}.vbhtml",
        "~/Views/_Base/Shared/{0}.cshtml",
        "~/Views/_Base/Shared/{0}.vbhtml"
        };
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        var PassedController = controllerContext.Controller as BaseController;
        Debug.Assert(PassedController != null, "PassedController != null");
        return base.CreatePartialView(controllerContext, GetTenantViewPath(partialPath, PassedController));
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        var PassedController = controllerContext.Controller as BaseController;
        Debug.Assert(PassedController != null, "PassedController != null");
        return base.CreateView(controllerContext, GetTenantViewPath(viewPath, PassedController), GetTenantViewPath(masterPath, PassedController));
    }

    protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
    {
        var PassedController = controllerContext.Controller as BaseController;
        Debug.Assert(PassedController != null, "PassedController != null");
        var tenantViewPath = GetTenantViewPath(virtualPath, PassedController);

        var isFound = base.FileExists(controllerContext, tenantViewPath);
        _logger.Debug(String.Format("Is Found: {0} Path: {1}.", isFound.ToString(), tenantViewPath));

        return isFound;
    }

    private string GetTenantViewPath(string virtualPath, BaseController PassedController)
    {
        string strReplacementString = "";

        if (PassedController == null)
        {
            strReplacementString = baseFolderPath;
        } 

        else if(PassedController.User == null) {
            strReplacementString = baseFolderPath;
        } 
        else 
        {
            strReplacementString = PassedController.User.CurrentAccountCode ?? baseFolderPath;
        }


        return virtualPath.Replace("%1", strReplacementString);
    }

    private readonly ILog _logger;
}

}

1 ответ

Оказывается, что в режиме релиза используется кэширование, которое вызывает проблемы, которые у меня были. Вам также необходимо переопределить методы FindView и FindPartialView и установить для useCache значение false:

//to not used Cached paths. see one of the comments here: http://lonetechie.com/2012/09/25/multi-tenant-architecture-with-asp-net-mvc-4/
        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            return base.FindView(controllerContext, viewName, masterName, false);
        }

        //to not used Cached paths. see one of the comments here: http://lonetechie.com/2012/09/25/multi-tenant-architecture-with-asp-net-mvc-4/
        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            return base.FindPartialView(controllerContext, partialViewName, false);
        }
Другие вопросы по тегам