Фреймворк Web API позволяет быстро и просто создавать HTTP-сервисы. В отличие от обычных ASP.Net MVC проектов, Web API не работает с представлениями. Используется контроллер специального вида, методы которого возвращают объекты модели.
Задача такого контроллера передавать данные, а не представления.
Давайте рассмотрим, как создать простой веб-сервис, предоставляющий отчеты FastReport.
1) Прежде всего создадим два отчета, которые будем отображать.
Шаблон отчета Simple List выглядит так:
Обратите внимание, что заголовок отчета имеет параметр [Parameter]. Нужно добавить параметр отчета с таким именем. Данные для этого отчета можно взять из таблицы Employee демонстрационной базы данных nwind.xml, которую можно найти тут: C:\Program Files (x86)\FastReports\FastReport.Net\Demos\Reports.
Шаблон второго отчета не будет содержать данные. Вы можете взять готовый шаблон Barcodes.frx из папки C:\Program Files (x86)\FastReports\FastReport.Net\Demos\Reports.
Как уже говорилось выше, мы будем использовать два отчета и одну базу данных в нашем проекте. Добавим их в папку App_Data. Делаем правый клик по этой папке в обозревателе решения. Выбираем Add->Existing item. Таким образом добавляем три файла: Barcode.frx, Simple List.frx, nwind.xml. Либо можно просто перетянуть эти файлы мышью в папку App_Data.
2) Создаем приложение ASP.NET:
Нажимаем Ок и переходим к выбору типа проекта:
Выбираем шаблон Empty. Внизу отмечаем опции MVC и Web API. Если вы выберите шаблон Web API, то получите проект, заполненный демонстрационными данными.
3) В Reference добавляем ссылку на библиотеку FastReport.dll.
4) Теперь, необходимо добавить модель данных. Для этого, в обозревателе решения, выбираем папку Model и делаем правый клик. В контекстном меню выбираем Add->Class:
Называем класс Reports.cs. Тип класса по умолчанию – Class. Нажимаем Add.
В созданный класс добавляем две переменные с методами get и set:
1 2 3 4 5 6 7 8 9 10 |
namespace FastReportWebApiDemo.Models { public class Reports { // Report ID public int Id { get; set; } // Report File Name public string ReportName { get; set; } } } |
5) Теперь добавим в проект контроллер. Делаем правый клик по папке Controllers. Из контекстного меню выбираем Add->Controller.
Выбираем шаблон контроллера – Web API2 Controller – Empty:
Назовем его ReportsController:
Переходим к кодированию логики в контроллере. Задача – обеспечить загрузку в браузере или отображение отчета в одном из форматов экспорта: PDF, HTML, png.
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using FastReport; using FastReport.Export.Image; using FastReport.Export.Html; using FastReport.Export.Pdf; using FastReport.Utils; using FastReportWebApiDemo.Models; using System.Web.Hosting; using System.Data; using System.IO; using System.Net.Http.Headers; namespace FastReportWebApiDemo.Controllers { //Класс параметров в запросе public class ReportQuery { // Format of resulting report: png, pdf, html public string Format { get; set; } // Value of "Parameter" variable in report public string Parameter { get; set; } // Enable Inline preview in browser (generates "inline" or "attachment") public bool Inline { get; set; } } public class ReportsController : ApiController { // Список отчетов Reports[] reportItems = new Reports[] { new Reports { Id = 1, ReportName = "Simple List.frx" }, new Reports { Id = 2, ReportName = "Barcode.frx" } }; // Получить список отчетов public IEnumerable<Reports> GetAllReports() { return reportItems; } // Получить отчет по ID из запроса public HttpResponseMessage GetReportById(int id, [FromUri] ReportQuery query) { // Найти отчет Reports reportItem = reportItems.FirstOrDefault((p) => p.Id == id); if (reportItem != null) { string reportPath = HostingEnvironment.MapPath("~/App_Data/" + reportItem.ReportName); string dataPath = HostingEnvironment.MapPath("~/App_Data/nwind-employees.xml"); MemoryStream stream = new MemoryStream(); try { using (DataSet dataSet = new DataSet()) { //Заполняем источник данными dataSet.ReadXml(dataPath); //Включаем веб режим FastReport Config.WebMode = true; using (Report report = new Report()) { report.Load(reportPath); //Загружаем отчет report.RegisterData(dataSet, "NorthWind"); //Регистрируем данные в отчете if (query.Parameter != null) { report.SetParameterValue("Parameter", query.Parameter); //Устанавливаем значение параметра в отчете. Само значение мы берем из URL } // Две фазы подготовки для исключения отображения каких-либо диалогов report.PreparePhase1(); report.PreparePhase2(); if (query.Format == "pdf") { //Экспорт отчета в PDF PDFExport pdf = new PDFExport(); //Используем поток для хранения отчета, чтобы не плодить файлы report.Export(pdf, stream); } else if (query.Format == "html") { //Экспорт отчета в HTML HTMLExport html = new HTMLExport(); html.SinglePage = true; html.Navigator = false; html.EmbedPictures = true; report.Export(html, stream); } else { //Экспорт в формат изображения ImageExport img = new ImageExport(); img.ImageFormat = ImageExportFormat.Png; img.SeparateFiles = false; img.ResolutionX = 96; img.ResolutionY = 96; report.Export(img, stream); query.Format = "png"; } } } //создаем результирующую переменную HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(stream.ToArray()) }; stream.Dispose(); result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue(query.Inline ? "inline" : "attachment") { //Задаем расширение файла в зависимости от типа экспорта FileName = String.Concat(Path.GetFileNameWithoutExtension(reportPath), ".", query.Format) }; //Определяем тип контента для браузера result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/" + query.Format); return result; } //Обрабатываем исключения catch { return new HttpResponseMessage(HttpStatusCode.InternalServerError); } } else return new HttpResponseMessage(HttpStatusCode.NotFound); } } } |
Как видите, мы добавили еще один класс в контроллер. В классе ReportQuery определяются параметры HTTP запроса. Это – format, parameter и inline. Первый определяет формат экспорта отчета, второй – значение параметра в отчете, третий – будет ли отчет открыт непосредственно в браузере.
В классе ReportsController мы создали массив отчетов и два метода. В массиве определены названия и идентификаторы отчетов. Первый метод GetAllReports() возвращает список доступных отчетов. В нашем случае два отчета. Второй метод GetReportById(int id, [FromUri] ReportQuery query) возвращает отчет по идентификатору. Из атрибута query мы можем получить параметры format, inline и parameter. Они определяют: формат экспорта отчета, будет ли отчет открыт непосредственно в браузере, значение параметра передаваемого в отчет.
6) Добавляем веб страницу в отчет. С помощью нее мы будем передавать запросы серверу с нужными параметрами. Для этого делаем правый клик по имени проекта. Выбираем Add->HTML Page:
Назовем страницу index:
Добавляем на страницу такой код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<!DOCTYPE html> <html> <head> <title>FastReport.Net Web Api Demo</title> <meta charset="utf-8" /> </head> <body> <h1>FastReport.Net Web Api Demo</h1> <hr /> <a href="/api/reports/">List Of All Reports</a><br /> <a href="/api/reports/1">Get First Report</a><br /> <a href="/api/reports/2">Get Second Report</a><br /> <a href="/api/reports/1?format=pdf">Get First Report in PDF</a><br /> <a href="/api/reports/2?format=html">Get Second Report in HTML</a><br /> <a href="/api/reports/1?format=pdf&inline=true">Get First Report in PDF inline</a><br /> <a href="/api/reports/2?format=html&inline=true">Get Second Report in HTML inline</a><br /> <a href="/api/reports/1?format=pdf&inline=true¶meter=REPORT">Get First Report in PDF inline with Parameter=REPORT</a><br /> <a href="/api/reports/1?format=html&inline=true¶meter=REPORT">Get First Report in HTML inline with Parameter=REPORT</a><br /> </body> </html> |
Как можно понять из названий, мы можем:
7) Открываем файл WebApiConfig.cs из папки App_Start. Добавляем еще один MapHttpRoute для страницы Index:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "Index", routeTemplate: "{id}.html", defaults: new { id = "index" } ); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } |
В этой же папке расположен файл RouteConfig.cs. Его можно удалить.
8) Последний шаг. Откройте файл Global.asax. Удалите строку:
1 |
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
Теперь роутинг будет осуществляться только через WebApiConfig.
9) Запускаем приложение. В браузере видим список команд:
На этом все. Работать с FastReport в WebAPI ничуть не сложнее, чем в обычном ASP.Net MVC проекте.