The Web API allows you to quickly and easily create HTTP services. Unlike regular ASP.Net MVC projects, the Web API does not work with views. A controller of a special type is used, the methods of which return model objects.
The task of such a controller is to transmit data, not representations.
Let's look at how to create a simple web service that provides FastReport reports.
1) First of all, we will create two reports, which we will display.
The simple list report template looks like this:
Note that the report header has the [Parameter] parameter. You need to add a report parameter with that name. Data for this report can be taken from the Employee table of the demonstration database nwind.xml, which can be found here: C: \ Program Files (x86) \ FastReports \ FastReport.Net \ Demos \ Reports.
The second report template will not contain data. You can take the ready-made template Barcodes.frx from the folder C: \ Program Files (x86) \ FastReports \ FastReport.Net \ Demos \ Reports.
As mentioned above, we will use two reports and one database in our project. Add them to the folder App_Data. Make a right click on this folder in the solution's browser. Choose Add-> Existing item. Thus we add three files: Barcode.frx, Simple List.frx, nwind.xml. Alternatively, you can simply drag these files to the App_Data folder with the mouse.
2) Create the ASP.NET application:
Click OK and go to the project type selection:
Select the Empty template. At the bottom mark MVC and Web API option. If you select a Web API template, you will receive a project filled with demo data.
3) Add a link to the FastReport.dll library in the Reference.
4) Now, you need to add a data model. To do this, in the solution browser, select the Model folder and make a right click. In the context menu, select Add-> Class:
Give the class name - Reports.cs. The default class type is Class. Click Add.
In the created class, add two variables with the get and set methods:
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) Now add the controller to the project. Do the right click on the Controllers folder. From the context menu, select Add-> Controller.
Select the controller template - Web API2 Controller - Empty:
Call it ReportsController:
Let's proceed to encoding the logic in the controller. The task is to provide a download in the browser or display the report in one of the export formats: 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 |
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 { // The class of parameters in the query 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 list Reports[] reportItems = new Reports[] { new Reports { Id = 1, ReportName = "Simple List.frx" }, new Reports { Id = 2, ReportName = "Barcode.frx" } }; // Get reports list public IEnumerable<Reports> GetAllReports() { return reportItems; } // Get report on ID from request public HttpResponseMessage GetReportById(int id, [FromUri] ReportQuery query) { // Find report 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()) { //Fill data source dataSet.ReadXml(dataPath); //Enable web mode Config.WebMode = true; using (Report report = new Report()) { report.Load(reportPath); //Load report report.RegisterData(dataSet, "NorthWind"); //Register Data in report if (query.Parameter != null) { report.SetParameterValue("Parameter", query.Parameter); // Set the value of the parameter in the report. The value we take from the URL } // Two phases of preparation to exclude the display of any dialogs report.PreparePhase1(); report.PreparePhase2(); if (query.Format == "pdf") { //Export in PDF PDFExport pdf = new PDFExport(); // We use the flow to store the report, so as not to produce files report.Export(pdf, stream); } else if (query.Format == "html") { // Export in HTML HTMLExport html = new HTMLExport(); html.SinglePage = true; html.Navigator = false; html.EmbedPictures = true; report.Export(html, stream); } else { // Export in picture ImageExport img = new ImageExport(); img.ImageFormat = ImageExportFormat.Png; img.SeparateFiles = false; img.ResolutionX = 96; img.ResolutionY = 96; report.Export(img, stream); query.Format = "png"; } } } // Create result variable 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") { // Specify the file extension depending on the type of export FileName = String.Concat(Path.GetFileNameWithoutExtension(reportPath), ".", query.Format) }; // Determine the type of content for the browser result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/" + query.Format); return result; } // We handle exceptions catch { return new HttpResponseMessage(HttpStatusCode.InternalServerError); } } else return new HttpResponseMessage(HttpStatusCode.NotFound); } } } |
As you can see, we added another class to the controller. The ReportQuery class defines the HTTP request parameters. This is format, parameter and inline. The first determines the format of the report export, the second one - the parameter value in the report, the third one - whether the report is opened directly in the browser.
In the ReportsController class, we created an array of reports and two methods. The names and report identifiers are defined in the array. The first method GetAllReports () returns a list of available reports. In our case, two reports. The second method GetReportById (int id, [FromUri] ReportQuery query) returns a report on the identifier. From the query attribute, we can get the parameters format, inline, and parameter. They determine: the export format of the report, whether the report will be opened directly in the browser, the value of the parameter to be sent to the report.
6) Add a web page to the report. With it, we will send requests to the server with the necessary parameters. To do this, right click on the project name. Choose Add-> HTML Page:
Set the name – Index:
Add the following code to the page:
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> |
As can be understood from the titles, we can:
1. Get a list of reports;
2. Get the first report. Based on our code in the controller, if we do not explicitly pass the format of the format, the report will be displayed in png format;
3. Receive a second report;
4. Get the first report in PDF format;
5. Get the second report in HTML format;
6. Get the first report in PDF format and display it in the browser;
7. Get the second report in HTML format and display it in the browser;
8. Get the first report in PDF format and display it in the browser, and also transfer it to the report.
9. Get the second report in HTML format and display it in the browser, and send it to the report.
7) Open the file WebApiConfig.cs from the folder App_Start. Add one more MapHttpRoute for the Index page:
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 } ); } |
In the same folder, the RouteConfig.cs file is located. It can be deleted.
8) The last step. Open the file Global.asax. Delete the line:
1 |
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
Now routing will be carried out only through WebApiConfig.
9) Run the application. In the browser we see a list of commands:
That's all. Working with FastReport in WebAPI is not more difficult than in the common ASP Net MVC project.