Это мой первый пост, извиняюсь, если вопрос нуждается в некоторых изменениях. Я выкинул эту проблему изо всех сил, но здесь много компонентов, так что этот пост довольно большой ...
Наш сайт ASP.NET MVC развернут как служба приложений в Azure. Я использую метод контроллера API для создания PDF страницы, которая существует на том же сайте. Для этого контроллер создает процесс PhantomJS, ожидает успеха и возвращает содержимое файла, который он создает. Это все работает нормально, но после этого несколько просмотров на сайте приводят к таким ошибкам:
Ошибка сервера в приложении '/'.
Каталог 'D: \ home \ site \ wwwroot \ Views \ Location' не существует. Не удалось запустить мониторинг изменений файла.
Описание: Произошло необработанное исключение во время выполнения текущего веб-запроса. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.
Сведения об исключении: System.Web.HttpException: Каталог 'D: \ home \ site \ wwwroot \ Views \ Location' не существует. Не удалось запустить мониторинг изменений файла.
Через некоторое время ошибка изменится:
Ошибка сервера в приложении '/'.
Представление LocationList или его мастер не найдены, или никакой движок представления не поддерживает найденные местоположения. Были найдены следующие местоположения:
~ / Просмотры / Location / LocationList.aspx
~ / Views / Location / LocationList.ascx
~ / Views / Shared / LocationList.aspx
~ / Views / Shared /LocationList.ascx
~/Views/Location/LocationList.cshtml
~/Views/Location/LocationList.vbhtml
~/Views/Shared/LocationList.cshtml
~/Views/Shared/LocationList .vbhtml
Описание: Произошло необработанное исключение во время выполнения текущего веб-запроса. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.
Сведения об исключении: System.InvalidOperationException: представление 'LocationList' или его мастер не найдены, или никакой механизм просмотра не поддерживает найденные местоположения. Были найдены следующие местоположения:
~ / Просмотры / Location / LocationList.aspx
~ / Views / Location / LocationList.ascx
~ / Views / Shared / LocationList.aspx
~ / Views / Shared /LocationList.ascx
~/Views/Location/LocationList.cshtml
~/Views/Location/LocationList.vbhtml
~/Views/Shared/LocationList.cshtml
~/Views/Shared/LocationList .vbhtml
Это относится только к представлениям, которые еще не скомпилированы или к любому другому файлу, к которому ранее не обращались. Единственный способ исправить это - вручную остановить и запустить веб-приложение. Я могу подтвердить, что это происходит не со всеми процессами (запуск «echo.exe» вместо «phantomjs.exe» не приводит к нарушению работы).
Я просмотрел все журналы, которые мог придумать, и не нашел ничего необычного. Мое лучшее предположение было бы, что процесс принудительно или случайно завершается, но что и почему, я понятия не имею. Может быть, есть какой-то важный журнал, о котором я не знаю?
Вот соответствующий код c #:
private static async Task<int> ExecuteSimpleAsync(string workingDir, double? timeout,
string command, params string[] parameters)
{
var paramStr = string.Join(" ", parameters.Select(x => x == null ? "" : $"\"{x}\"").ToList());
var processInfo = new ProcessStartInfo(command, paramStr) {
WorkingDirectory = workingDir,
UseShellExecute = false,
CreateNoWindow = true,
};
Process process = null;
int exitCode = -1;
using (process = new Process() { StartInfo = processInfo }) {
process.Start();
await process.WaitForExitAsync(timeout); // simple extension function to check for 'Process.HasExited' periodically
exitCode = process.ExitCode;
}
return exitCode;
}
private static async Task<byte[]> GetFileContents(string filePath) {
byte[] bytes = null;
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read)) {
bytes = new byte[file.Length];
await file.ReadAsync(bytes, 0, (int) file.Length);
}
return bytes;
}
public static async Task<byte[]> RenderPdfAsync(
string cookiesB64, string localUrl, string baseFilename, double? timeout = 60)
{
....
// filesPath: (directory for temporary output)
// timeout: 60.000 (60 seconds)
// PhantomJSExePath: (absolute path containing 'phantomjs.exe')
// scriptFile: "rasterize_simple.js"
// requestUrl: "TestReport/ForUserAndTestPdf/1002/10"
// outputFile: "phantomjs-output-<timestamp>.pdf"
// cookiesB64: (base64-encoded authentication cookies passed to request in PhantomJS)
var exitCode = await ExecuteSimpleAsync(filesPath, timeout, PhantomJSExePath + @"\phantomjs.exe",
scriptFile, requestUrl, outputFile, cookiesB64);
if (exitCode != 0)
return null;
return await GetFileContents(outputFile);
}
[Authorize]
[HttpGet]
[Route("TestReport/ForUserAndTestPdf/{userId}/{testId}")]
public async Task<HttpResponseMessage> ForUserAndTestPdfAsync(int userId, int testId) {
// produce a slightly-modified version of the current URL:
// /TestReport/ForUserAndTest/<userid>/<testid>
// => /TestReport/ForUserAndTestPdf/<userid>/<testid>?print=true
var url = Request.RequestUri.GetLocalPathWithParams("print=true").Replace("ForUserAndTest", "ForUserAndTestPdf");
// get the cookies used in the current request and convert to a base64-encoded JSON object
var cookiesB64 = Request.GetCookiesJsonB64();
var bytes = await PhantomJSHelpers.RenderPdfAsync(cookiesB64, url, "phantomjs-output", 60);
var message = new HttpResponseMessage(HttpStatusCode.OK);
message.Content = new StreamContent(new MemoryStream(bytes));
message.Content.Headers.ContentLength = bytes.Length;
message.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
return message;
}
Вот соответствующая часть скрипта "rasterize_simple.js", используемого PhantomJS, без настройки размера страницы, файлов cookie и т. Д .:
page.open(address, function(status) {
page.render(outputFilename);
phantom.exit(0);
});
Ожидаемым результатом всего этого является файл PDF, который он генерирует, и все последующие вызовы этого метода API (с другими параметрами) работают отлично. Тем не менее, побочным эффектом является полностью нарушенный сайт: (
Любая помощь здесь будет принята с благодарностью!