Мы уже рассмотрели, как сделать рассылку отчета на группу email из базы данных. В этой статье мы сделаем то же самое, но для веб приложения на платформе .NET Core MVC. Напомню, наша задача - получить список электронных адресов и имен пользователей из некой базы данных и, отправить письма с прикрепленным отчетом на эти почтовые ящики. Воспользуемся базой данных MS SQL Server.
Создадим приложение ASP .NET Core MVC приложение. Прежде всего добавим необходимые библиотеки в проект с помощью NuGet Packages Manager. В общем хранилище nuget находим и устанавливаем пакеты:
Из локального репозитория – папки Nuget в директории установки FastReport .NET устанавливаем пакеты:
А теперь создадим контекст работы с базой данных и класс-сущность таблицы. Для этого нужно открыть консоль пакетов 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. Просто для красоты. Давайте запустим приложение и посмотрим, как выглядит наша веб страница:
Отправляем письма разными методами:
И:
В первом случае, в тексте письма мы обращаемся к клиенту по имени, во втором нет.
На этом все.