The example shows how to allow end users to save a dashboard to a session and download a dashboard XML definition on the client side. For this, use the corresponding Download and Save As… buttons in the Toolbox.
Files to Review
- SessionDashboardStorage.cs
- downloadAndSaveAsExtension.js
- scripts.js
- HomeController.cs
- Global.asax.cs
- Index.cshtml
Documentation
Does this example address your development requirements/objectives?
(you will be redirected to DevExpress.com to submit your response)
Example Code
C#using System;
using System.Collections.Generic;
using System.Xml.Linq;
using DevExpress.DashboardCommon;
using DevExpress.DashboardWeb;
using System.Web;
using System.Web.SessionState;
namespace DevExpress.PublicDemo {
public class SessionDashboardStorage : DashboardStorageBase {
const string DashboardStorageKey = "DashboardStorage";
private static SessionDashboardStorage instance = null;
public static SessionDashboardStorage Instance {
get {
if(instance == null) {
instance = new SessionDashboardStorage();
}
return instance;
}
}
Dictionary<string, XDocument> Storage {
get {
HttpSessionState session = HttpContext.Current.Session;
if(session != null) {
Dictionary<string, XDocument> storage = session[DashboardStorageKey] as Dictionary<string, XDocument>;
if(storage == null) {
storage = new Dictionary<string, XDocument>();
session[DashboardStorageKey] = storage;
return storage;
}
return storage;
}
throw new ArgumentNullException("Session is not available");
}
}
protected SessionDashboardStorage() : base() {
}
protected override IEnumerable<string> GetAvailableDashboardsID() {
return Storage.Keys;
}
protected override XDocument LoadDashboard(string dashboardID) {
return Storage[dashboardID];
}
protected override void SaveDashboard(string dashboardID, XDocument dashboard, bool createNew) {
if(createNew ^ Storage.ContainsKey(dashboardID))
Storage[dashboardID] = dashboard;
}
public void RegisterDashboard(string dashboardID, XDocument dashboard) {
SaveDashboard(dashboardID, dashboard, true);
}
}
}
JavaScriptvar TOOLBAR_DOWNLOAD_ICON = '<svg id="toolbar-download" viewBox="0 0 24 24"><path fill="#39A866" d="M12 2 L2 22 L22 22 Z" /></svg>';
var TOOLBAR_SAVE_AS_ICON = '<svg version="1.1" id="toolbar-save-as" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve"><style type="text/css">.dx_white{fill:#FFFFFF;}.dx_darkgray{fill:#414141;}.dx_green{fill:#39A866;}</style><path class="dx_green" d="M21,2H3C2.4,2,2,2.4,2,3v18c0,0.6,0.4,1,1,1h3v-6h12v6h3c0.6,0,1-0.4,1-1V3C22,2.4,21.6,2,21,2z"/><rect x="14" y="18" class="dx_darkgray" width="2" height="4"/><path class="dx_darkgray" d="M15,13h8c0.6,0,1-0.4,1-1V4.4c0-0.3-0.1-0.5-0.3-0.7l-2.4-2.4C21.1,1.1,20.9,1,20.6,1H15c-0.6,0-1,0.4-1,1v10C14,12.6,14.4,13,15,13z"/><polygon class="dx_white" points="16,11 22,11 22,5 20,5 20,3 16,3 "/></svg>';
function DownloadAndSaveAsDashboardExtension(dashboardControl) {
var _this = this;
this.name = "save-as";
this.newName = "New Dashboard Name";
this.toolbox = dashboardControl.findExtension("toolbox");
DevExpress.Dashboard.ResourceManager.registerIcon(TOOLBAR_DOWNLOAD_ICON);
DevExpress.Dashboard.ResourceManager.registerIcon(TOOLBAR_SAVE_AS_ICON);
this._menuSaveAsItem = new DevExpress.Dashboard.Designer.DashboardMenuItem("save-as", "Save As...", 120, 0, function() { _this.showSaveAsPopup(); });
this._menuSaveAsItem.hasSeparator = true;
this._menuSaveAsItem.data = _this;
this._toolbarGroup = new DevExpress.Dashboard.Designer.DashboardToolbarGroup("save", "Save", 60,
new DevExpress.Dashboard.Designer.DashboardToolbarItem("download", function () { window.open(baseDevExpressDemoUrl + "Home/Xml/?dashboardId=" + dashboardControl.dashboardContainer().id, '_blank'); }, "toolbar-download", "Download"),
new DevExpress.Dashboard.Designer.DashboardToolbarItem("save-as", function () { _this.showSaveAsPopup(); }, "toolbar-save-as", "Save As...")
);
this.showSaveAsPopup = function () {
_this.popup.show();
$("#textBoxContainer").dxTextBox({
value: _this.newName,
onValueChanged: function (e) {
_this.newName = e.value;
}
});
}
this.hideSaveAsPopup = function () {
dashboardControl.findExtension("toolbox").menuVisible(false);
_this.popup.hide();
}
this.popup = createPopup(function () {
dashboardControl.findExtension("create-dashboard").performCreateDashboard(_this.newName, dashboardControl.dashboard().getJSON());
_this.hideSaveAsPopup();
}, function () {
_this.hideSaveAsPopup();
});
}
DownloadAndSaveAsDashboardExtension.prototype.start = function () {
this.toolbox.menuItems.push(this._menuSaveAsItem);
this.toolbox.toolbarGroups.push(this._toolbarGroup);
this.toolbox.menuItems().filter(function (item) { return item.id === "save" })[0].hasSeparator = false;
};
DownloadAndSaveAsDashboardExtension.prototype.stop = function () {
this.toolbox.menuItems.remove(this._menuSaveAsItem);
this.toolbox.toolbarGroups.remove(this._toolbarGroup);
};
function createPopup(saveButtonAction, cancelButtonAction) {
return $("#popupContainer").dxPopup({
title: "Save As...",
width: 400,
height: 185,
toolbarItems: [{
toolbar: "bottom",
widget: "dxButton",
location: "after",
options: {
text: "Save",
onClick: saveButtonAction
}
}, {
toolbar: "bottom",
widget: "dxButton",
location: "after",
options: {
text: "Cancel",
onClick: cancelButtonAction
}
}]
}).dxPopup("instance");
}
JavaScriptfunction onBeforeRender(sender, eventArgs) {
var dashboardControl = sender.getDashboardControl();
dashboardControl.registerExtension(new DevExpress.Dashboard.DashboardPanelExtension(dashboardControl));
dashboardControl.registerExtension(new DownloadAndSaveAsDashboardExtension(dashboardControl))
}
C#using System;
using System.Linq;
using System.Web.Mvc;
using DevExpress.DashboardWeb;
using System.Xml.Linq;
using System.IO;
using System.Collections.Generic;
namespace dxMvcDashboardSample {
public partial class HomeController : Controller {
public ActionResult Index(string workingMode, string dashboardId) {
return View("Index", new DashboardControlModel {
DashboardId = dashboardId,
WorkingMode = string.IsNullOrEmpty(workingMode) ? WorkingMode.Designer : (WorkingMode)Enum.Parse(typeof(WorkingMode), workingMode)
});
}
public ActionResult Viewer(string dashboardId) {
return View("Index", new DashboardControlModel {
DashboardId = dashboardId,
WorkingMode = WorkingMode.ViewerOnly
});
}
public ActionResult Xml(string dashboardId) {
IDashboardStorage st = DevExpress.PublicDemo.SessionDashboardStorage.Instance as IDashboardStorage;
if(string.IsNullOrEmpty(dashboardId)) {
IEnumerable<DashboardInfo> dashboards = st.GetAvailableDashboardsInfo();
dashboardId = ((DashboardInfo)dashboards.ElementAt(0)).ID;
}
XDocument xdoc = st.LoadDashboard(dashboardId);
MemoryStream stream = new MemoryStream();
xdoc.Save(stream);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, System.Net.Mime.MediaTypeNames.Application.Octet, dashboardId + ".xml");
}
}
public class DashboardControlModel {
public string DashboardId { get; set; }
public WorkingMode WorkingMode { get; set; }
}
}
C#using System.Web.Mvc;
using System.Web.Routing;
using DevExpress.DashboardWeb;
using DevExpress.DashboardWeb.Mvc;
using DevExpress.Web.Mvc;
using System.Xml.Linq;
using DevExpress.DashboardCommon;
using DevExpress.DataAccess.Excel;
using DevExpress.Security.Resources;
namespace DevExpress.Razor {
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes) {
routes.MapDashboardRoute("dashboardControl", "DefaultDashboard");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Session_Start() {
RegisterDefaultDashboard("Presidents");
}
protected void Application_Start() {
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ModelBinders.Binders.DefaultBinder = new DevExpressEditorsBinder();
AccessSettings.StaticResources.TrySetRules(DirectoryAccessRule.Allow());
// See https://documentation.devexpress.com/Dashboard/DevExpress.DashboardWeb.DashboardFileStorage.class
//DashboardConfigurator.Default.SetDashboardStorage(new DashboardFileStorage(@"~/App_Data/Dashboards"));
DashboardConfigurator.Default.SetDashboardStorage(PublicDemo.SessionDashboardStorage.Instance);// this code based on DevExpress demo
DashboardExcelDataSource ds = new DashboardExcelDataSource("Excel Data Source");
ds.SourceOptions = new ExcelSourceOptions(new ExcelWorksheetSettings("List"));
ds.FileName = @"|DataDirectory|Data\PresidentsData.xlsx";
DataSourceInMemoryStorage dataSourceStorage = new DataSourceInMemoryStorage();
dataSourceStorage.RegisterDataSource("dashboardExcelDataSource1", ds.SaveToXml());
DashboardConfigurator.Default.SetDataSourceStorage(dataSourceStorage);
}
void RegisterDefaultDashboard(string dashboardId) {
string dashboardLocalPath = Server.MapPath(string.Format(@"~/App_Data/Dashboards/{0}.xml", dashboardId));
PublicDemo.SessionDashboardStorage.Instance.RegisterDashboard(dashboardId, XDocument.Load(dashboardLocalPath));
}
}
}
Razor@model DashboardControlModel
@using DevExpress.DashboardWeb;
@using System.Web.Mvc;
@using System.Web.UI.WebControls;
@{
Layout = "../Shared/_Layout.cshtml";
}
<script type="text/javascript">
var baseDevExpressDemoUrl = '@(Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~"))';
</script>
<div style="position: absolute; left:0;top:0;right:0;bottom:0;">
@Html.DevExpress().Dashboard(settings => {
settings.Name = "dashboardControl";
settings.ControllerName = "DefaultDashboard";
settings.InitialDashboardId = String.IsNullOrEmpty(Model.DashboardId) ? "Presidents" : Model.DashboardId;
settings.Width = Unit.Percentage(100);
settings.Height = Unit.Percentage(100);
settings.WorkingMode = Model.WorkingMode;
settings.AllowExportDashboardItems = false;
settings.ClientSideEvents.BeforeRender = "onBeforeRender";
}).GetHtml()
</div>