Example T566760
Visible to All Users

Reporting for ASP.NET MVC - How to Email a Report from the Document Viewer

This example adds a custom action button to the Document Viewer that triggers a custom operation on the server side. The server-side custom operation exports a report to HTML and PDF, and emails the resulting documents.

When you run the application, you observe the Document Viewer with a newly added action button:

Document Viewer with a Custom Button to Email a Report

To email a report, click the button. The application attempts to send email to someone@test.com using the localhost SMTP server, port 25. Modify the code to apply your mail server settings.

The report sent by email is shown in the following image:

Report Sent by Email

When the user clicks the 'Send via Email' button, the client-side PerformCustomDocumentOperation method passes data to the DocumentOperationService on the server. The service exports the report to PDF and HTML formats, creates the MIME message and sends email using the MailKIt client.

The PerformCustomDocumentOperation method returns an object that implements the IDocumentOperationResult interface, so you can return the data from the DocumentOperationService to the client.

Files to Review

Documentation

More Examples

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

CustomDocumentOperationService/Global.asax.cs(vb)
C#
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Routing; using DevExpress.Web.Mvc; using DevExpress.XtraReports.Services; using DevExpress.XtraReports.Web.WebDocumentViewer; namespace DocumentOperationServiceSample { // Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { DevExpress.XtraReports.Web.WebDocumentViewer.Native.WebDocumentViewerBootstrapper.SessionState = System.Web.SessionState.SessionStateBehavior.Default; DefaultWebDocumentViewerContainer.Register<DocumentOperationService, Services.CustomDocumentOperationService>(); DevExpress.XtraReports.Web.WebDocumentViewer.DefaultWebDocumentViewerContainer.Register<IReportProvider, Services.ReportProvider>(); MVCxWebDocumentViewer.StaticInitialize(); AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); ModelBinders.Binders.DefaultBinder = new DevExpress.Web.Mvc.DevExpressEditorsBinder(); DevExpress.Web.ASPxWebControl.CallbackError += Application_Error; } protected void Application_Error(object sender, EventArgs e) { Exception exception = System.Web.HttpContext.Current.Server.GetLastError(); //TODO: Handle Exception } } }
CustomDocumentOperationService/Services/CustomDocumentOperationService.cs(vb)
C#
using System; using System.IO; using DevExpress.XtraPrinting; using DevExpress.XtraReports.Web.WebDocumentViewer; using DevExpress.XtraReports.Web.WebDocumentViewer.DataContracts; using MailKit.Security; namespace DocumentOperationServiceSample.Services { public class CustomDocumentOperationService : DocumentOperationService { public override bool CanPerformOperation(DocumentOperationRequest request) { return true; } public override DocumentOperationResponse PerformOperation(DocumentOperationRequest request, PrintingSystemBase initialPrintingSystem, PrintingSystemBase printingSystemWithEditingFields) { using (var stream = new MemoryStream()) { System.Net.Mail.MailMessage mMessage = printingSystemWithEditingFields.ExportToMail(request.CustomData, "john.doe@test.com", "John Doe"); mMessage.Subject = "Test"; // Create a new attachment and add the PDF document. printingSystemWithEditingFields.ExportToPdf(stream); stream.Seek(0, System.IO.SeekOrigin.Begin); System.Net.Mail.Attachment attachedDoc = new System.Net.Mail.Attachment(stream, "TestReport.pdf", "application/pdf"); mMessage.Attachments.Add(attachedDoc); var message = (MimeKit.MimeMessage)mMessage; string smtpHost = "localhost"; int smtpPort = 25; using (message) { using (var client = new MailKit.Net.Smtp.SmtpClient()) { try { client.Connect(smtpHost, smtpPort, SecureSocketOptions.Auto); //client.Authenticate(userName, password); client.Send(message); client.Disconnect(true); return new DocumentOperationResponse { Succeeded = true, Message = "Mail was sent successfully", DocumentId = printingSystemWithEditingFields.Document.Name }; } catch (Exception ex) { return new DocumentOperationResponse { Message = ex.Message, Succeeded = false, }; } } } } } protected string RemoveNewLineSymbols(string value) { return value; } } }
CustomDocumentOperationService/Views/Home/Viewer.cshtml
Razor
<style> .custom-image-item { background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjYgMjYiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDI2IDI2OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe2ZpbGw6IzNEM0QzRDt9PC9zdHlsZT48Zz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjUsN2MwLTAuMi0wLjEtMC42LTAuMy0wLjdDMjQuNiw2LjEsMjQuNCw2LDI0LjIsNkgxNnY1LjdsMS45LDEuN0wyNSw3eiIvPjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xLDIybDE0LDNWMUwxLDRWMjJ6IE04LDEwYzEuNywwLDMsMS44LDMsNGMwLDIuMi0xLjMsNC0zLDRzLTMtMS44LTMtNEM1LDExLjgsNi4zLDEwLDgsMTB6Ii8+PHBhdGggY2xhc3M9InN0MCIgZD0iTTE4LDE1bC0yLTJsMCw4bDguMiwwYzAuMiwwLDAuNC0wLjEsMC42LTAuM2MwLjItMC4yLDAuMi0wLjQsMC4yLTAuNkwyNSw5TDE4LDE1TDE4LDE1eiIvPjxlbGxpcHNlIGNsYXNzPSJzdDAiIGN4PSI4IiBjeT0iMTQiIHJ4PSIyIiByeT0iMyIvPjwvZz48L3N2Zz4NCg==); background-repeat: no-repeat; } </style> <script> function CustomizeMenuActions(s, e) { var itemDisabled = ko.observable(true); s.Init.AddHandler(function (s) { var reportPreview = s.GetReportPreview(); reportPreview.events.on('propertyChanged', (e) => { if(e.propertyName === 'exportDisabled') { itemDisabled(e.newValue); } }); itemDisabled(reportPreview.exportDisabled); }); var sendViaEmailItem = { id: 'someCustomId', imageClassName: 'custom-image-item', text: 'Send via Email', visible: true, disabled: itemDisabled, clickAction: function () { var previewModel = s.GetPreviewModel(); s.PerformCustomDocumentOperation('someone@test.com') .then((arg) => alert('Document ' + arg.documentId + " : " + arg.message)); } }; e.Actions.push(sendViaEmailItem); } </script> @Html.DevExpress().WebDocumentViewer(settings => { settings.Name = "WebDocumentViewer1"; settings.ClientSideEvents.CustomizeMenuActions = "CustomizeMenuActions"; }).Bind("CategoriesReport").GetHtml()
CustomDocumentOperationService/Views/Home/Viewer.vbhtml
Code
<style> .custom-image-item { background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjYgMjYiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDI2IDI2OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PHN0eWxlIHR5cGU9InRleHQvY3NzIj4uc3Qwe2ZpbGw6IzNEM0QzRDt9PC9zdHlsZT48Zz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjUsN2MwLTAuMi0wLjEtMC42LTAuMy0wLjdDMjQuNiw2LjEsMjQuNCw2LDI0LjIsNkgxNnY1LjdsMS45LDEuN0wyNSw3eiIvPjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xLDIybDE0LDNWMUwxLDRWMjJ6IE04LDEwYzEuNywwLDMsMS44LDMsNGMwLDIuMi0xLjMsNC0zLDRzLTMtMS44LTMtNEM1LDExLjgsNi4zLDEwLDgsMTB6Ii8+PHBhdGggY2xhc3M9InN0MCIgZD0iTTE4LDE1bC0yLTJsMCw4bDguMiwwYzAuMiwwLDAuNC0wLjEsMC42LTAuM2MwLjItMC4yLDAuMi0wLjQsMC4yLTAuNkwyNSw5TDE4LDE1TDE4LDE1eiIvPjxlbGxpcHNlIGNsYXNzPSJzdDAiIGN4PSI4IiBjeT0iMTQiIHJ4PSIyIiByeT0iMyIvPjwvZz48L3N2Zz4NCg==); background-repeat: no-repeat; } </style> <script> function CustomizeMenuActions(s, e) { var itemDisabled = ko.observable(true); s.Init.AddHandler(function (s) { var reportPreview = s.GetReportPreview(); reportPreview.events.on('propertyChanged', (e) => { if(e.propertyName === 'exportDisabled') { itemDisabled(e.newValue); } }); itemDisabled(reportPreview.exportDisabled); }); var sendViaEmailItem = { id: 'someCustomId', imageClassName: 'custom-image-item', text: 'Send via Email', visible: true, disabled: itemDisabled, clickAction: function () { s.PerformCustomDocumentOperation('someone@test.com') .done((arg) => alert('Document ' + arg.documentId + " : " + arg.message)); } }; e.Actions.push(sendViaEmailItem); } </script> @Html.DevExpress().WebDocumentViewer( Sub(settings) settings.Name = "WebDocumentViewer1" settings.ClientSideEvents.CustomizeMenuActions = "CustomizeMenuActions" End Sub).Bind("CategoriesReport").GetHtml()

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.