Электронная почта Hangfire + Crystal Reports?

Я пытаюсь сделать так, чтобы мы могли ежедневно создавать определенные отчеты и отправлять их по электронной почте группе людей в списке.

Я тестировал Hangfire на повторяющиеся задания, и он хорошо работает. Так что это не проблема. Но я пытаюсь создать отчет из моего существующего файла Crystal Report (.rpt). По сути, я хочу сделать так, чтобы при выполнении этого задания код создавал отчет, сохранял его на диск по указанному пути в виде PDF-файла, а затем я мог отправить его людям по электронной почте в виде вложения. Таким образом, нет необходимости видеть отчет на веб-странице. Идея состоит в том, чтобы буквально просто сгенерировать отчет в исходном коде, сохранить его как PDF-файл и отправить его по электронной почте из исходного кода после его сохранения.

Проблема, с которой я столкнулся, связана с фактическим созданием и сохранением отчета о кристалле. Кстати, я создаю файл Excel в тесте, но я бы изменил его на PDF для фактического отчета. Вот что у меня есть для создания отчета:

        string path = @"Save folder relative-path";
        //"report" is declared at the class level and instantiated below.
        report = new ReportDocument();
        report.SetDatabaseLogon(ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);
        report.Load(Server.MapPath("Relative path to the report"));
        report.SetDataSource(GetDataSet()); //This gets the dataset filled with data for the report

        try
        {
            ExportOptions options = new ExportOptions();

            DiskFileDestinationOptions diskFileOptions = new DiskFileDestinationOptions();
            ExcelFormatOptions excelOptions = new ExcelFormatOptions();
            diskFileOptions.DiskFileName = path + "Test Report.xls";

            options.ExportDestinationType = ExportDestinationType.DiskFile;
            options.ExportFormatType = ExportFormatType.Excel;
            options.ExportDestinationOptions = diskFileOptions;
            options.ExportFormatOptions = excelOptions;
            report.Export();

            /*
            This is where I would call a method to email the report to people
            */
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error generating report: " + ex.Message);
        }

Этот код находится в методе, который вызывается в Application_Start в файле global.asax веб-приложения. Когда я запускаю приложение, задание завершается сбоем и выдает эту ошибку, когда я смотрю под неудачными заданиями на панели инструментов Hangfire, хотя я знаю, что путь в моем коде правильный:

System.IO.FileNotFoundException Не удалось загрузить файл или сборку «App_global.asax.twm32qri, Version = 0.0.0.0, Culture = нейтральный, PublicKeyToken = null» или одну из их зависимостей. Система не может найти указанный файл.

System.IO.FileNotFoundException: не удалось загрузить файл или сборку App_global.asax.twm32qri, Version = 0.0.0.0, Culture = нейтральный, PublicKeyToken = null или одну из его зависимостей. Система не может найти указанный файл. Имя файла: 'App_global.asax.twm32qri, Version = 0.0.0.0, Culture = нейтральный, PublicKeyToken = null' в System.RuntimeTypeHandle.GetTypeByName (String name, Boolean throwOnError, Boolean ignoreCase, Boolean ReflectionOnly, StackCrawlMasterStackCrawl loadTypeFromPartialName, тип ObjectHandleOnStack) в System.RuntimeTypeHandle.GetTypeByName (имя String, Boolean, Boolean throwOnError IgnoreCase, булевой reflectionOnly, StackCrawlMark & ​​stackMark, IntPtr pPrivHostBinder, булева loadTypeFromPartialName) в System.Type.GetType (String, Boolean TypeName throwOnError, Boolean IgnoreCase) в Hangfire.Storage.InvocationData.Deserialize ()

WRN: ведение журнала привязки сборки отключено. Чтобы включить ведение журнала сбоев привязки сборок, установите для параметра реестра [HKLM \ Software \ Microsoft \ Fusion! EnableLog] (DWORD) значение 1. Примечание. Ведение журнала сбоев привязки сборок приводит к некоторому снижению производительности. Чтобы отключить эту функцию, удалите значение реестра [HKLM \ Software \ Microsoft \ Fusion! EnableLog].

РЕДАКТИРОВАТЬ:

Я тоже получаю еще одну ошибку. Это как-то связано с загрузкой файла отчета.

Failed Исключительная ситуация во время выполнения задания. CrystalDecisions.CrystalReports.Engine.LoadSaveReportException

Неверный путь к файлу отчета.

CrystalDecisions.CrystalReports.Engine.LoadSaveReportException: недопустимый путь к файлу отчета. в CrystalDecisions.CrystalReports.Engine.ExceptionThrower.ThrowEngineException (String messageID, EngineExceptionErrorID id) в CrystalDecisions.CrystalReports.Engine.ReportDocument.Load (имя файла String, OpenReportMethod openMethod.CrystalReports.ParentReports.at CrystalDecisions.CrystalReports.Engine.ReportDocument.SetDatabaseLogon (строковый пользователь, строковый пароль) в Intranet.Global.GenerateReport () в пути \ Global.asax.cs: строка 98


person David Flynn    schedule 17.06.2015    source источник
comment
Это исключение не от Crystal ... не уверен, что такое Hangfire или почему вам нужно написать это в веб-приложении, но, по-видимому, он не загружает сборку для global.asax   -  person dotjoe    schedule 17.06.2015
comment
@dotjoe Hangfire предназначен для создания фоновых заданий, которые по своей природе могут быть простыми и забытыми, отложенными или повторяющимися. Мой будет повторяться, так как я буду отправлять отчет по электронной почте ежедневно. Я так понимаю, что ошибка не от кристалла. Но я не знаю, как сгенерировать и сохранить отчет на диск.   -  person David Flynn    schedule 17.06.2015
comment
Какую ошибку вы получаете при экспорте на диск? Разрешения на запись для целевого каталога в порядке?   -  person dotjoe    schedule 17.06.2015
comment
@dotjoe Я включил ошибку в вопрос. Это System.IO.FileNotFoundException. Разрешения на запись точно есть.   -  person David Flynn    schedule 17.06.2015
comment
да, но это исключение запускается еще до того, как вы дойдете до кода Crystal, верно ??   -  person dotjoe    schedule 17.06.2015
comment
@dotjoe на самом деле подожди, теперь я получаю еще одну ошибку, когда просматриваю историю этого задания. Я отредактирую сообщение, чтобы включить сюда и эту ошибку, через минуту.   -  person David Flynn    schedule 17.06.2015
comment
Возможно, удалите эту попытку, чтобы могло всплыть полное исключение из экспорта кристаллов.   -  person dotjoe    schedule 17.06.2015
comment
Вы должны установить вход в базу данных после загрузки отчета.   -  person dotjoe    schedule 17.06.2015
comment
Вам нужен вход в систему? Потому что похоже, что вы вставляете набор данных в отчет ...   -  person dotjoe    schedule 17.06.2015
comment
@dotjoe Полагаю, мне не нужен вход в систему. Я добавил набор данных позже, так как простой вход в базу данных не работал, даже если файл отчета настроен и все для получения данных, если он получает учетные данные для входа. Я переместил код входа в систему под строкой загрузки и получил эту ошибку: Операция сервера System.Web.HttpException недоступна в этом контексте. System.Web.HttpException (0x80004005): операция сервера недоступна в этом контексте. в System.Web.HttpServerUtility.MapPath (строковый путь) в Intranet.Global.GenerateReport () в * path * \ Global.asax.cs: строка 98   -  person David Flynn    schedule 17.06.2015
comment
Позвольте нам продолжить это обсуждение в чате.   -  person dotjoe    schedule 17.06.2015


Ответы (1)


Разобрался в проблеме. Очевидно, мне нужно было использовать объект CrystalReportViewer и установить объект ReportDocument в качестве его источника. Класс CrystalReportViewer находится в пространстве имен CrystalDecisions.Web.

using (ReportDocument report = new ReportDocument())
{
    using (CrystalReportViewer viewer = new CrystalReportViewer())
    {
        string path = System.Web.Hosting.HostingEnvironment.MapPath(@"Destination path here");
        report.Load(System.Web.Hosting.HostingEnvironment.MapPath(@"Path to .rpt file here"));
        report.SetDatabaseLogon(ConfigurationManager.AppSettings["Username"], ConfigurationManager.AppSettings["Password"]);

        string file = path + "TestReport.xls";

        //These two lines below are important. The report won't generate without them.
        viewer.ReportSource = report;
        viewer.RefreshReport();

        //Just deleting the file if it exists.
        if (File.Exists(file))
            File.Delete(file);

        report.ExportToDisk(ExportFormatType.Excel, diskFileOptions.DiskFileName);
    }
}
person David Flynn    schedule 18.06.2015