Example T893871
Visible to All Users

Dashboard for MVC - How to handle errors

The following example demostrates two approaches on how to handle errors in the ASP.NET MVC Dashboard application:

Both projects in this example override the OnException method. You can also handle the ASPxWebControl.CallbackError event to customize error text. See the following example for details about this approach: ASP.NET Web Forms Dashboard - How to handle errors

How to specify custom text for internal Dashboard errors

Files to Review

Description

The dashboard in this project contains invalid data connection. This example shows how to override the OnException method in a custom dashboard controller to specify custom text in the exception. The exception occurs when the controller tries to load data.

  1. Create a custom dashboard controller and override the OnException method. You can specify the displayed text depending on whether the application is in development mode.
  2. Specify the created custom controller's name in the view.
  3. Use the created CustomDashboard controller when you map a dashboard route.

How to throw a custom exception during a server-side processing and display the error in the Dashboard error toast

Files to Review

Description

This example shows how to throw a custom exception when a controller loads a dashboard and display this exception in the dashboard error toast. The example overrides the OnException method.

  • Create a custom dashboard controller and override the OnException method. You can specify the displayed text depending on whether the application is in development mode.
  • Specify the created custom controller's name in the view.
  • Use the created CustomDashboard controller when you map a dashboard route.
  • To throw an exception when the control loads a dashboard, create custom dashboard storage and override the LoadDashboard method.

Documentation

More Examples

Example Code

MvcCustomTextForInternalDashboardErrors/Global.asax.cs(vb)
C#
using DevExpress.DashboardCommon; using DevExpress.DashboardWeb; using DevExpress.DataAccess.ConnectionParameters; using DevExpress.DataAccess.Sql; using System.Web.Mvc; using System.Web.Routing; namespace MvcCustomTextForInternalDashboardErrors { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { DashboardConfig.RegisterService(RouteTable.Routes); AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory(typeof(RestrictedControllerFactory)); DataSourceInMemoryStorage dataSourceStrorage = new DataSourceInMemoryStorage(); DashboardSqlDataSource sql = new DashboardSqlDataSource("sql", "sqlConn"); sql.Queries.Add(SelectQueryFluentBuilder.AddTable("Products").SelectAllColumns().Build("query")); dataSourceStrorage.RegisterDataSource(sql.SaveToXml()); DashboardConfigurator.Default.SetDashboardStorage(new DashboardFileStorage(Server.MapPath("~/App_Data/Dashboards"))); DashboardConfigurator.Default.SetDataSourceStorage(dataSourceStrorage); DashboardConfigurator.Default.ConfigureDataConnection += ASPxDashboard1_ConfigureDataConnection; } void ASPxDashboard1_ConfigureDataConnection(object sender, ConfigureDataConnectionWebEventArgs e) { // Invalid connection parameters: switch (e.ConnectionName) { case "sqlConn": e.ConnectionParameters = new MsSqlConnectionParameters(@"localhost", "Northwind123", null, null, MsSqlAuthorizationType.Windows); break; } } } }
MvcCustomTextForInternalDashboardErrors/Controllers/CustomDashboardController.cs(vb)
C#
using DevExpress.DashboardWeb.Mvc; using System; using System.Net; using System.Web.Mvc; namespace MvcCustomTextForInternalDashboardErrors { public class CustomDashboardController : DashboardController { protected override void OnException(ExceptionContext context) { var exception = context.Exception; if(exception != null && context.HttpContext != null) { var response = context.HttpContext.Response; response.StatusCode = (int)HttpStatusCode.BadRequest; response.ContentType = "application/json"; // The 'mode' attribute in the 'customErrors' section of the Web.config file specifies whether an application is in development mode. bool isCustomErrorsEnabled = System.Web.HttpContext.Current != null ? System.Web.HttpContext.Current.IsCustomErrorEnabled : true; response.Write(GetJson(isCustomErrorsEnabled ? "Custom exception text for end users" : "Custom exception text for developers")); context.ExceptionHandled = true; } } static string GetJson(string message) { return $"{{ \"Message\":\"{message}\" }}"; } } }
MvcCustomTextForInternalDashboardErrors/App_Start/DashboardConfig.cs(vb)
C#
using DevExpress.DashboardWeb.Mvc; using System.Web.Routing; namespace MvcCustomTextForInternalDashboardErrors { public class DashboardConfig { public static void RegisterService(RouteCollection routes) { //routes.MapDashboardRoute(); // Uncomment this line to save dashboards to the App_Data folder. //DashboardConfigurator.Default.SetDashboardStorage(new DashboardFileStorage(@"~/App_Data/")); // Uncomment these lines to create an in-memory storage of dashboard data sources. Use the DataSourceInMemoryStorage.RegisterDataSource // method to register the existing data source in the created storage. //var dataSourceStorage = new DataSourceInMemoryStorage(); //DashboardConfigurator.Default.SetDataSourceStorage(dataSourceStorage); routes.MapDashboardRoute("dashboardDesigner", "CustomDashboard", new string[] { "MvcCustomTextForInternalDashboardErrors" }); } } }
MvcCustomTextForInternalDashboardErrors/Views/Default/Index.cshtml
Razor
@using System.Web.UI.WebControls <!DOCTYPE html> <html> <head> @Html.DevExpress().GetStyleSheets( new StyleSheet { ExtensionSuite = ExtensionSuite.NavigationAndLayout }, new StyleSheet { ExtensionSuite = ExtensionSuite.Editors }, new StyleSheet { ExtensionSuite = ExtensionSuite.Dashboard } ) @Html.DevExpress().GetScripts( new Script { ExtensionSuite = ExtensionSuite.NavigationAndLayout }, new Script { ExtensionSuite = ExtensionSuite.Editors }, new Script { ExtensionSuite = ExtensionSuite.Dashboard } ) <style type="text/css"> html, body, form { height: 100%; margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> @Html.DevExpress().Dashboard(settings => { settings.Name = "Dashboard"; settings.ControllerName = "CustomDashboard"; settings.Width = Unit.Percentage(100); settings.Height = Unit.Percentage(100); }).GetHtml() </body> </html>
MvcCustomTextForInternalDashboardErrors/Views/Default/Index.vbhtml
Code
@Imports System.Web.UI.WebControls <!DOCTYPE html> <html> <head> @Html.DevExpress().GetStyleSheets( New StyleSheet With {.ExtensionSuite = ExtensionSuite.NavigationAndLayout}, New StyleSheet With {.ExtensionSuite = ExtensionSuite.Editors}, New StyleSheet With {.ExtensionSuite = ExtensionSuite.Dashboard} ) @Html.DevExpress().GetScripts( New Script With {.ExtensionSuite = ExtensionSuite.NavigationAndLayout}, New Script With {.ExtensionSuite = ExtensionSuite.Editors}, New Script With {.ExtensionSuite = ExtensionSuite.Dashboard} ) <style type="text/css"> html, body, form { height: 100%; margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> @Html.DevExpress().Dashboard( Sub(settings) settings.ControllerName = "CustomDashboard" settings.Name = "Dashboard" settings.Width = Unit.Percentage(100) settings.Height = Unit.Percentage(100) End Sub).GetHtml() </body> </html>
MvcThrowCustomExceptionDashboardErrorToast/Global.asax.cs(vb)
C#
using System; using System.Collections.Generic; using System.Web.Mvc; using System.Web.Routing; using System.Xml.Linq; using DevExpress.DashboardWeb; namespace MvcThrowCustomExceptionDashboardErrorToast { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { ControllerBuilder.Current.SetControllerFactory(typeof(RestrictedControllerFactory)); DashboardConfig.RegisterService(RouteTable.Routes); AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); DashboardConfigurator.Default.SetDashboardStorage(new CustomDashboardStorage()); } } public class CustomException : Exception { public const string SafeMessage = "Custom exception text for end users"; public const string UnsafeMessage = "Custom exception text for developers"; } public class CustomDashboardStorage : IDashboardStorage { IEnumerable<DashboardInfo> IDashboardStorage.GetAvailableDashboardsInfo() { return new[] { new DashboardInfo { ID = "Dashboard", Name = "Dashboard" } }; } XDocument IDashboardStorage.LoadDashboard(string dashboardID) { throw new CustomException(); } void IDashboardStorage.SaveDashboard(string dashboardID, XDocument dashboard) { } } }
MvcThrowCustomExceptionDashboardErrorToast/App_Start/DashboardConfig.cs(vb)
C#
using System.Web.Routing; using DevExpress.DashboardWeb; using DevExpress.DashboardWeb.Mvc; namespace MvcThrowCustomExceptionDashboardErrorToast { public class DashboardConfig { public static void RegisterService(RouteCollection routes) { //routes.MapDashboardRoute(); // Uncomment this line to save dashboards to the App_Data folder. //DashboardConfigurator.Default.SetDashboardStorage(new DashboardFileStorage(@"~/App_Data/")); // Uncomment these lines to create an in-memory storage of dashboard data sources. Use the DataSourceInMemoryStorage.RegisterDataSource // method to register the existing data source in the created storage. //var dataSourceStorage = new DataSourceInMemoryStorage(); //DashboardConfigurator.Default.SetDataSourceStorage(dataSourceStorage); routes.MapDashboardRoute("dashboardDesigner", "CustomDashboard", new string[] { "MvcThrowCustomExceptionDashboardErrorToast" }); } } }
MvcThrowCustomExceptionDashboardErrorToast/Controllers/CustomDashboardController.cs(vb)
C#
using System.Net; using System.Web.Mvc; using DevExpress.DashboardWeb.Mvc; namespace MvcThrowCustomExceptionDashboardErrorToast.Controllers { public class CustomDashboardController : DashboardController { protected override void OnException(ExceptionContext context) { var exception = context.Exception; if(exception != null && context.HttpContext != null) { var response = context.HttpContext.Response; response.StatusCode = (int)HttpStatusCode.BadRequest; response.ContentType = "application/json"; CustomException customException = exception as CustomException; bool isCustomErrorsEnabled = System.Web.HttpContext.Current != null ? System.Web.HttpContext.Current.IsCustomErrorEnabled : true; string message = customException != null ? (isCustomErrorsEnabled ? CustomException.SafeMessage : CustomException.UnsafeMessage) : ""; response.Write(GetJson(message)); context.ExceptionHandled = true; } } static string GetJson(string message) { return $"{{ \"Message\":\"{message}\" }}"; } } }
MvcThrowCustomExceptionDashboardErrorToast/Views/Default/Index.cshtml
Razor
@using System.Web.UI.WebControls <!DOCTYPE html> <html> <head> @Html.DevExpress().GetStyleSheets( new StyleSheet { ExtensionSuite = ExtensionSuite.NavigationAndLayout }, new StyleSheet { ExtensionSuite = ExtensionSuite.Editors }, new StyleSheet { ExtensionSuite = ExtensionSuite.Dashboard } ) @Html.DevExpress().GetScripts( new Script { ExtensionSuite = ExtensionSuite.NavigationAndLayout }, new Script { ExtensionSuite = ExtensionSuite.Editors }, new Script { ExtensionSuite = ExtensionSuite.Dashboard } ) <style type="text/css"> html, body, form { height: 100%; margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> @Html.DevExpress().Dashboard(settings => { settings.ControllerName = "CustomDashboard"; settings.Name = "Dashboard"; settings.Width = Unit.Percentage(100); settings.Height = Unit.Percentage(100); }).GetHtml() </body> </html>
MvcThrowCustomExceptionDashboardErrorToast/Views/Default/Index.vbhtml
Code
@Imports System.Web.UI.WebControls <!DOCTYPE html> <html> <head> @Html.DevExpress().GetStyleSheets( New StyleSheet With {.ExtensionSuite = ExtensionSuite.NavigationAndLayout}, New StyleSheet With {.ExtensionSuite = ExtensionSuite.Editors}, New StyleSheet With {.ExtensionSuite = ExtensionSuite.Dashboard} ) @Html.DevExpress().GetScripts( New Script With {.ExtensionSuite = ExtensionSuite.NavigationAndLayout}, New Script With {.ExtensionSuite = ExtensionSuite.Editors}, New Script With {.ExtensionSuite = ExtensionSuite.Dashboard} ) <style type="text/css"> html, body, form { height: 100%; margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> @Html.DevExpress().Dashboard( Sub(settings) settings.ControllerName = "CustomDashboard" settings.Name = "Dashboard" settings.Width = Unit.Percentage(100) settings.Height = Unit.Percentage(100) End Sub).GetHtml() </body> </html>

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.