Как сделать рассылку отчета на Email из базы данных в .NET Core приложении

08.03.2019

Мы уже рассмотрели, как сделать рассылку отчета на группу email из базы данных. В этой статье мы сделаем то же самое, но для веб приложения на платформе .NET Core MVC. Напомню, наша задача - получить список электронных адресов и имен пользователей из некой базы данных и, отправить письма с прикрепленным отчетом на эти почтовые ящики. Воспользуемся базой данных MS SQL Server.

 

Создадим приложение ASP .NET Core MVC приложение. Прежде всего добавим необходимые библиотеки в проект с помощью NuGet Packages Manager. В общем хранилище nuget находим и устанавливаем пакеты:

  • Microsoft.EntityFrameworkCore;
  • Microsoft.EntityFrameworkCore.Relational;
  • Microsoft.jQuery.Unobtrusive.Ajax;
  • jQuery.

Из локального репозитория – папки Nuget в директории установки FastReport .NET устанавливаем пакеты:

  • FastReport.Core;
  • FastReport.Web.

А теперь создадим контекст работы с базой данных и класс-сущность таблицы. Для этого нужно открыть консоль пакетов Nuget. Открываем меню Tools -> Nuget Package Manager -> Package Manager Console. В консоли набираем следующую команду:

scaffold-dbcontext "Server=localhost;Database=testdb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

Конечно же тут вы должны задать свою строку подключения к серверу БД и папку для модели данных (по умолчанию Models).

PM> scaffold-dbcontext "Server=localhost;Database=testdb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

После этого, по идее, в папке Models должно добавиться два файла: конекст и сущность таблицы. В моем случае это testdbContext.cs и Emails.cs.

Однако, во время генерации файлов может возникнуть ошибка:

error MSB4064: The "SharedCompilationId" parameter is not supported by the "Csc" task. There is a settable public instance property.

Если это случилось, то добавьте в менеджере пакетов NuGet еще один пакет:

Microsoft.Net.Compillers

Давайте сразу подключим FastReport к нашему проекту. В файле Startup.cs добавим строку:

1
2
3
4
5
6
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 {

 app.UseFastReport();

}

Теперь вернемся к модели данных. Чтобы получить записи из базы нам нужно создать метод GetEmails. Создадим класс-фасад для работы с данными:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace WebMailing.Models
{
 public static class Facade
 {
 public static List<Emails> GetEmails()
 {
 using (Models.testdbContext context = new Models.testdbContext())
 {
 var emails = (from adresses in context.Emails
 select adresses).ToList();
 return emails;
 }
 }
 }
}

Перейдем к контроллеру HomeController. В методе Index загрузим отчет, чтобы отобразить его на главной странице сайта:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using WebMailing.Models;
using FastReport;
using FastReport.Export.Pdf;
using FastReport.Export.Email;
using FastReport.Web;

public IActionResult Index()
{
 WebReport webReport = new WebReport();
 webReport.Report.Load(Environment.CurrentDirectory + "/text.frx");
 ViewBag.WebReport = webReport;
 return View();
}

Мы добавим два метода отправки писем. Первый будет отправлять персональные письма с указанием имени клиента в приветствии, второй – будет отправлять одно письмо на группу адресов. Итак, первый метод:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[HttpPost]
 public ActionResult SendMail()
 {
 Report report1 = new Report(); //Create new report object
 report1.Load(Environment.CurrentDirectory + "/text.frx"); //Load report
 report1.Prepare(); //Prepare report
 
 PDFExport pdf = new PDFExport(); //Cteate PDF export
 EmailExport email = new EmailExport(); //Create Email export
 
 List<Emails> emails = Models.Facade.GetEmails();
 foreach (Emails item in emails)
 {
 SendMessage(report1, pdf, email, item.Email, item.Name);
 }
 return View();
 }

В нем мы создали отчет, экспорт в PDF, экспорт в Email. Затем, в цикле мы получаем записи из таблицы и вызываем метод отправки письма. В качестве параметров, мы передаем в него объект отчета, экспорт PDF, экспорт в Email, Email адрес и имя клиента. А вот сам метод отправки письма:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void SendMessage(Report report, PDFExport pdf, EmailExport email, string recipient, string custName)
 {
 string message = "This is test message.";
 email.Account.Address = "gromozekaster@yandex.ru";
 email.Account.Name = "Test User";
 email.Account.Host = "smtp.yandex.ru";
 email.Account.Port = 25;
 email.Account.UserName = "Gromozekaster";
 email.Account.Password = "*****"; //Your password
 email.Account.MessageTemplate = "Test";
 email.Account.EnableSSL = true;
 //email addressee settings
 email.Address = recipient;
 email.Subject = "TestMessage";
 email.MessageBody = custName is null ? message : string.Format("Dear, {0}! {1}", custName, message);
 email.Export = pdf; //Set export type
 email.SendEmail(report); //Send email
 }

В нем мы настраиваем почтовый клиент для отправки письма. И сразу же добавим второй метод отправки одного письма на группу адресов:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 [HttpPost]
 public ActionResult SendAll()
 {
 Report report1 = new Report(); //Create new report object
 report1.Load(Environment.CurrentDirectory + "/text.frx"); //Load report
 report1.Prepare(); //Prepare report
 PDFExport pdf = new PDFExport(); //Cteate PDF export
 EmailExport email = new EmailExport(); //Create Email export
 
 List<Emails> emails = Models.Facade.GetEmails();
 string addresses = "";
 foreach (Emails item in emails)
 {
 if (addresses == "")
 addresses = item.Email;
 else
 addresses = addresses + ", " + item.Email;
 }
 SendMessage(report1, pdf, email, addresses, null);
 return View();
 }

Как видите, он очень похож на предыдущий метод, с той лишь разницей, что в цикле мы получаем все email адреса, а отправляем письмо один раз. В качестве параметра email мы передаем строковую переменную со всеми email адресами, а имя клиента не передаем.

Для обоих методов SendMail() и SendAll() мы должны создать одноименные представления – view.

Их содержимое предельно просто:

1
2
3
4
@{
 ViewBag.Message = "Report was sent";
}
@ViewBag.Message

Мы просто информируем об отправке.

Перейдем к представлению Index.cshtml. В нем мы должны добавить две кнопки для отправки писем разными методами, а также отобразить отчет:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@{
 ViewData["Title"] = "Home Page";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
 <form action="SendMail" method="POST">
 <input type="button" id="SendPersonal" value="Send Personal Email">
 <input type="button" id="SendAll" value="Send Email to All">
 <div class="answer"/>
 </form>
 <script type="text/javascript">
 $('#SendPersonal').on("click", function () {
 $.ajax({
 type: 'POST', // dispatch method
 url: '@Url.Action("SendMail", "Home")', // path to handler
 dataType: 'text',
 success: function (data) {
 $(".answer").html(data); // upon successful receipt of the response from the server, we enter the data in the element with the class answer
 }
 });
 return false;
 })
 $('#SendAll').on("click", function () {
 $.ajax({
 type: 'POST', // dispatch method
 url: '@Url.Action("SendAll", "Home")', // path to handler
 dataType: 'text',
 success: function (data) {
 $(".answer").html(data); // upon successful receipt of the response from the server, we enter the data in the element with the class answer
 }
 });
 return false;
 })
 </script>
@await ViewBag.WebReport.Render() 

Чтобы использовать ajax jquery мы добавляем ссылку на скрипт jquery.min.js. Далее добавляем форму с двумя кнопками и два скрипта для каждой из них. Скрипты предельно просты – вызов метода из контроллера и возврат результирующего представления.

В конце – выводим отчет из метода Index. Просто для красоты. Давайте запустим приложение и посмотрим, как выглядит наша веб страница:

Отправляем письма разными методами:

 

И:

 

В первом случае, в тексте письма мы обращаемся к клиенту по имени, во втором нет.

На этом все.

20 ноября 2024

Локализация и смена языков в FastReport VCL

FastReport VCL поддерживает 40 языков для локализации интерфейса и позволяет изменять язык на лету через меню или код, без перекомпиляции.
1 ноября 2024

Новые возможности редактора отчетов FastReport VCL

Рассматриваем новые возможности редактора отчетов: выносные линии, подсветка пересекающихся объектов, обновлённые деревья отчетов и данных.
30 октября 2024

Использование стилей при создании отчетов в FastReport VCL

В статье подробно рассматривается одна из новых возможностей FastReport VCL – применение стилей и страниц стилей.