├── .gitignore ├── LICENSE ├── MvcReportViewer.sln ├── MvcReportViewer ├── AzureReportServerCredentials.cs ├── BaseLocalDataSourceProvider.cs ├── Configuration │ ├── MvcReportViewerSettings.cs │ └── ReportViewerConfiguration.cs ├── ControlSettings.cs ├── ControlSettingsManager.cs ├── ILocalReportDataSourceProvider.cs ├── IMvcReportViewerOptions.cs ├── IReportViewerEventsHandler.cs ├── IgnoreCaseExtensions.cs ├── LocalReportDataSourceProviderFactory.cs ├── MvcReportViewer.aspx ├── MvcReportViewer.aspx.cs ├── MvcReportViewer.csproj ├── MvcReportViewerException.cs ├── MvcReportViewerExtensions.cs ├── MvcReportViewerIframe.cs ├── Properties │ └── AssemblyInfo.cs ├── ReportFormat.cs ├── ReportRunner.cs ├── ReportRunnerExtensions.cs ├── ReportServerCredentials.cs ├── ReportViewerExtensions.cs ├── ReportViewerParameters.cs ├── ReportViewerParametersParser.cs ├── SecurityUtil.cs ├── SessionLocalDataSourceProvider.cs ├── SqlLocalDataSourceProvider.cs ├── UriParameterAttribute.cs ├── UriParameters.cs └── packages.config ├── MvcReportViewerExample ├── .gitattributes ├── App_Data │ ├── Database.mdf │ ├── Database_log.ldf │ └── Reports │ │ ├── Cities.rdlc │ │ ├── CitiesByCountry.rdlc │ │ ├── Countries.rdlc │ │ ├── DatabaseDataSet.Designer.cs │ │ ├── DatabaseDataSet.xsc │ │ ├── DatabaseDataSet.xsd │ │ ├── DatabaseDataSet.xss │ │ ├── ListCountries.rdlc │ │ ├── NoDataReport.rdlc │ │ └── Products.rdlc ├── App_Start │ ├── FilterConfig.cs │ ├── NinjectWebCommon.cs │ ├── RouteConfig.cs │ └── WebApiConfig.cs ├── Content │ └── styles.css ├── Controllers │ └── HomeController.cs ├── Global.asax ├── Global.asax.cs ├── Models │ ├── LocalData.cs │ ├── LocalReportsModel.cs │ ├── SqlLocalReportsModel.cs │ ├── SubreportEventHandlers.cs │ └── SubreportModel.cs ├── MvcReportViewer.aspx ├── MvcReportViewerErrorPage.html ├── MvcReportViewerExample.csproj ├── Properties │ └── AssemblyInfo.cs ├── Scripts │ ├── MvcReportViewer.js │ └── url.js ├── Views │ ├── Home │ │ ├── DrillThrough.cshtml │ │ ├── Fluent.cshtml │ │ ├── Index.cshtml │ │ ├── LocalReports.cshtml │ │ ├── Multiple.cshtml │ │ ├── NoDataLocalReport.cshtml │ │ ├── Post.cshtml │ │ ├── Subreport.cshtml │ │ └── VisibilityCheck.cshtml │ ├── Shared │ │ └── _Layout.cshtml │ ├── Web.config │ └── _ViewStart.cshtml ├── Web.Debug.config ├── Web.Release.config ├── Web.config └── packages.config ├── MvcReportViewerTests ├── .gitattributes ├── App.config ├── DataSourceCredentialsTests.cs ├── HtmlHelperFactory.cs ├── IframeTests.cs ├── MvcReportViewerIframeFluentTests.cs ├── MvcReportViewerIframeTests.cs ├── MvcReportViewerTests.csproj ├── Properties │ └── AssemblyInfo.cs ├── ReportRunnerTests.cs ├── ReportViewerParametersParserTests.cs ├── TestData.cs ├── TestHelpers.cs └── packages.config ├── MvcReportViewer_NET45 ├── Configuration │ └── placeholder.txt ├── Libs │ └── Microsoft.ReportViewer.WebForms.DLL ├── MvcReportViewer_NET45.csproj ├── Properties │ └── placeholder.txt └── packages.config ├── README.md └── nuget ├── MvcReportViewer.0.1.0.nupkg ├── MvcReportViewer.0.2.0.nupkg ├── MvcReportViewer.0.2.1.nupkg ├── MvcReportViewer.0.3.0.nupkg ├── MvcReportViewer.0.3.1.nupkg ├── MvcReportViewer.0.4.0.nupkg ├── MvcReportViewer.0.4.1.nupkg ├── MvcReportViewer.0.4.2.nupkg ├── MvcReportViewer.0.4.3.nupkg ├── MvcReportViewer.0.4.4.nupkg ├── MvcReportViewer.0.5.0.nupkg ├── MvcReportViewer.0.5.1.nupkg ├── MvcReportViewer.0.5.2.nupkg ├── MvcReportViewer.0.6.0.nupkg ├── MvcReportViewer.0.6.1.nupkg ├── MvcReportViewer.0.6.2.nupkg ├── MvcReportViewer.0.6.3.nupkg ├── MvcReportViewer.0.7.0.nupkg ├── MvcReportViewer.0.7.1.nupkg ├── MvcReportViewer.0.7.2.nupkg ├── MvcReportViewer.0.7.3.nupkg ├── MvcReportViewer.0.7.4.nupkg ├── MvcReportViewer.0.8.0.nupkg ├── MvcReportViewer.0.8.1.nupkg ├── MvcReportViewer.0.8.2.nupkg ├── MvcReportViewer.0.8.3.nupkg ├── MvcReportViewer.nuspec ├── content ├── MvcReportViewer.aspx ├── MvcReportViewerErrorPage.html ├── Scripts │ ├── MvcReportViewer.js │ └── url.js └── web.config.transform └── lib ├── net40 └── MvcReportViewer.dll └── net45 └── MvcReportViewer.dll /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | .vs/ 16 | 17 | # Build results 18 | [Dd]ebug/ 19 | [Rr]elease/ 20 | x64/ 21 | *_i.c 22 | *_p.c 23 | *.ilk 24 | *.meta 25 | *.obj 26 | *.pch 27 | *.pdb 28 | *.pgc 29 | *.pgd 30 | *.rsp 31 | *.sbr 32 | *.tlb 33 | *.tli 34 | *.tlh 35 | *.tmp 36 | *.log 37 | *.vspscc 38 | *.vssscc 39 | .builds 40 | 41 | # Visual C++ cache files 42 | ipch/ 43 | *.aps 44 | *.ncb 45 | *.opensdf 46 | *.sdf 47 | 48 | # Visual Studio profiler 49 | *.psess 50 | *.vsp 51 | *.vspx 52 | 53 | # Guidance Automation Toolkit 54 | *.gpState 55 | 56 | # ReSharper is a .NET coding add-in 57 | _ReSharper* 58 | 59 | # NCrunch 60 | *.ncrunch* 61 | .*crunch*.local.xml 62 | 63 | # Installshield output folder 64 | [Ee]xpress 65 | 66 | # DocProject is a documentation generator add-in 67 | DocProject/buildhelp/ 68 | DocProject/Help/*.HxT 69 | DocProject/Help/*.HxC 70 | DocProject/Help/*.hhc 71 | DocProject/Help/*.hhk 72 | DocProject/Help/*.hhp 73 | DocProject/Help/Html2 74 | DocProject/Help/html 75 | 76 | # Click-Once directory 77 | publish 78 | 79 | # Publish Web Output 80 | *.Publish.xml 81 | 82 | # NuGet Packages Directory 83 | packages 84 | 85 | # Windows Azure Build Output 86 | csx 87 | *.build.csdef 88 | 89 | # Windows Store app package directory 90 | AppPackages/ 91 | 92 | # Others 93 | [Bb]in 94 | [Oo]bj 95 | sql 96 | TestResults 97 | [Tt]est[Rr]esult* 98 | *.Cache 99 | ClientBin 100 | [Ss]tyle[Cc]op.* 101 | ~$* 102 | *.dbmdl 103 | Generated_Code #added for RIA/Silverlight projects 104 | 105 | # Backup & report files from converting an old project file to a newer 106 | # Visual Studio version. Backup files are not needed, because we have git ;-) 107 | _UpgradeReport_Files/ 108 | Backup*/ 109 | UpgradeLog*.XML 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2015 Ilya Verbitskiy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /MvcReportViewer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MvcReportViewerExample", "MvcReportViewerExample\MvcReportViewerExample.csproj", "{5804FFD3-29D6-42FA-943B-94DE747CBE24}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MvcReportViewer", "MvcReportViewer\MvcReportViewer.csproj", "{6353720D-C784-4C00-A7B7-D652542FBCC9}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MvcReportViewerTests", "MvcReportViewerTests\MvcReportViewerTests.csproj", "{20D0F976-2730-406D-A336-4056416CFF10}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MvcReportViewer_NET45", "MvcReportViewer_NET45\MvcReportViewer_NET45.csproj", "{BF8D2B0B-EFD0-44A6-B6E1-A3215B4C477B}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {5804FFD3-29D6-42FA-943B-94DE747CBE24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {5804FFD3-29D6-42FA-943B-94DE747CBE24}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {5804FFD3-29D6-42FA-943B-94DE747CBE24}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {5804FFD3-29D6-42FA-943B-94DE747CBE24}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {6353720D-C784-4C00-A7B7-D652542FBCC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {6353720D-C784-4C00-A7B7-D652542FBCC9}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {6353720D-C784-4C00-A7B7-D652542FBCC9}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {6353720D-C784-4C00-A7B7-D652542FBCC9}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {20D0F976-2730-406D-A336-4056416CFF10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {20D0F976-2730-406D-A336-4056416CFF10}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {20D0F976-2730-406D-A336-4056416CFF10}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {20D0F976-2730-406D-A336-4056416CFF10}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {BF8D2B0B-EFD0-44A6-B6E1-A3215B4C477B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {BF8D2B0B-EFD0-44A6-B6E1-A3215B4C477B}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {BF8D2B0B-EFD0-44A6-B6E1-A3215B4C477B}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {BF8D2B0B-EFD0-44A6-B6E1-A3215B4C477B}.Release|Any CPU.Build.0 = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /MvcReportViewer/AzureReportServerCredentials.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Reporting.WebForms; 2 | using System.Net; 3 | using System.Security.Principal; 4 | 5 | namespace MvcReportViewer 6 | { 7 | // Please check http://msdn.microsoft.com/en-us/library/gg552871.aspx#Authentication for 8 | // additional details or if you have found a bug in this code. 9 | 10 | internal class AzureReportServerCredentials : IReportServerCredentials 11 | { 12 | private readonly string _username; 13 | 14 | private readonly string _password; 15 | 16 | private readonly string _server; 17 | 18 | public AzureReportServerCredentials(string username, string password, string server) 19 | { 20 | _username = username; 21 | _password = password; 22 | _server = server; 23 | } 24 | 25 | public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority) 26 | { 27 | authCookie = null; 28 | userName = _username; 29 | password = _password; 30 | authority = _server; 31 | return true; 32 | } 33 | 34 | public WindowsIdentity ImpersonationUser => null; 35 | 36 | public ICredentials NetworkCredentials => null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MvcReportViewer/BaseLocalDataSourceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcReportViewer 4 | { 5 | public abstract class BaseLocalDataSourceProvider 6 | { 7 | protected virtual string GetSessionValueKey(Guid reportControlId) 8 | { 9 | return $"MvcReportViewer_Local_{reportControlId}"; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MvcReportViewer/Configuration/MvcReportViewerSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | 3 | namespace MvcReportViewer.Configuration 4 | { 5 | public class MvcReportViewerSettings : ConfigurationSection 6 | { 7 | [ConfigurationProperty("reportServerUrl")] 8 | public string ReportServerUrl 9 | { 10 | get { return this["reportServerUrl"] as string; } 11 | set { this["reportServerUrl"] = value; } 12 | } 13 | 14 | [ConfigurationProperty("username")] 15 | public string Username 16 | { 17 | get { return this["username"] as string; } 18 | set { this["username"] = value; } 19 | } 20 | 21 | [ConfigurationProperty("password")] 22 | public string Password 23 | { 24 | get { return this["password"] as string; } 25 | set { this["password"] = value; } 26 | } 27 | 28 | [ConfigurationProperty("aspxViewer", DefaultValue = "~/MvcReportViewer.aspx")] 29 | public string AspxViewer 30 | { 31 | get { return this["aspxViewer"] as string; } 32 | set { this["aspxViewer"] = value; } 33 | } 34 | 35 | [ConfigurationProperty("aspxViewerJavaScript", DefaultValue = "~/Scripts/MvcReportViewer.js")] 36 | public string AspxViewerJavaScript 37 | { 38 | get { return this["aspxViewerJavaScript"] as string; } 39 | set { this["aspxViewerJavaScript"] = value; } 40 | } 41 | 42 | [ConfigurationProperty("errorPage", DefaultValue = "~/MvcReportViewerErrorPage.html")] 43 | public string ErrorPage 44 | { 45 | get { return this["errorPage"] as string; } 46 | set { this["errorPage"] = value; } 47 | } 48 | 49 | [ConfigurationProperty("showErrorPage", DefaultValue = false)] 50 | public bool ShowErrorPage 51 | { 52 | get { return (bool)this["showErrorPage"]; } 53 | set { this["showErrorPage"] = value; } 54 | } 55 | 56 | [ConfigurationProperty("isAzureSSRS", DefaultValue = false)] 57 | // ReSharper disable once InconsistentNaming 58 | public bool IsAzureSSRS 59 | { 60 | get { return (bool)this["isAzureSSRS"]; } 61 | set { this["isAzureSSRS"] = value; } 62 | } 63 | 64 | [ConfigurationProperty("encryptParameters", DefaultValue = false)] 65 | public bool EncryptParameters 66 | { 67 | get { return (bool)this["encryptParameters"]; } 68 | set { this["encryptParameters"] = value; } 69 | } 70 | 71 | [ConfigurationProperty("localDataSourceProvider")] 72 | public string LocalDataSourceProvider 73 | { 74 | get { return this["localDataSourceProvider"] as string; } 75 | set { this["localDataSourceProvider"] = value; } 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /MvcReportViewer/Configuration/ReportViewerConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | 3 | namespace MvcReportViewer.Configuration 4 | { 5 | class ReportViewerConfiguration 6 | { 7 | private readonly MvcReportViewerSettings _settings; 8 | 9 | public ReportViewerConfiguration(string configSection = "MvcReportViewer") 10 | { 11 | _settings = ConfigurationManager.GetSection(configSection) as MvcReportViewerSettings; 12 | } 13 | 14 | public string ReportServerUrl => _settings != null 15 | ? _settings.ReportServerUrl 16 | : ConfigurationManager.AppSettings["MvcReportViewer.ReportServerUrl"]; 17 | 18 | public string Username => _settings != null 19 | ? _settings.Username 20 | : ConfigurationManager.AppSettings["MvcReportViewer.Username"]; 21 | 22 | public string Password => _settings != null 23 | ? _settings.Password 24 | : ConfigurationManager.AppSettings["MvcReportViewer.Password"]; 25 | 26 | public string AspxViewer => _settings != null 27 | ? _settings.AspxViewer 28 | : ConfigurationManager.AppSettings["MvcReportViewer.AspxViewer"]; 29 | 30 | public string AspxViewerJavaScript => _settings != null 31 | ? _settings.AspxViewerJavaScript 32 | : ConfigurationManager.AppSettings["MvcReportViewer.AspxViewerJavaScript"]; 33 | 34 | public string ErrorPage => _settings != null 35 | ? _settings.ErrorPage 36 | : ConfigurationManager.AppSettings["MvcReportViewer.ErrorPage"]; 37 | 38 | public bool ShowErrorPage => _settings?.ShowErrorPage ?? ReadBoolConfig("MvcReportViewer.ShowErrorPage"); 39 | 40 | // ReSharper disable once InconsistentNaming 41 | public bool IsAzureSSRS => _settings?.IsAzureSSRS ?? ReadBoolConfig("MvcReportViewer.IsAzureSSRS"); 42 | 43 | public bool EncryptParameters => _settings?.EncryptParameters ?? ReadBoolConfig("MvcReportViewer.EncryptParameters"); 44 | 45 | public string LocalDataSourceProvider => _settings != null 46 | ? _settings.LocalDataSourceProvider 47 | : ConfigurationManager.AppSettings["MvcReportViewer.LocalDataSourceProvider"]; 48 | 49 | private static bool ReadBoolConfig(string config) 50 | { 51 | var strValue = ConfigurationManager.AppSettings[config]; 52 | 53 | bool value; 54 | return bool.TryParse(strValue, out value) && value; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /MvcReportViewer/ControlSettingsManager.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Reporting.WebForms; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Collections.Specialized; 5 | using System.Drawing; 6 | using System.Globalization; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Web.UI.WebControls; 10 | 11 | namespace MvcReportViewer 12 | { 13 | internal class ControlSettingsManager 14 | { 15 | private static readonly Dictionary UriParameters = new Dictionary(); 16 | 17 | private static readonly Dictionary Properties = new Dictionary(); 18 | 19 | private readonly bool _isEncrypted; 20 | 21 | static ControlSettingsManager() 22 | { 23 | var type = typeof(ControlSettings); 24 | foreach(var property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) 25 | { 26 | var uriAttr = property.GetCustomAttributes(typeof(UriParameterAttribute), false) 27 | .FirstOrDefault() as UriParameterAttribute; 28 | if (uriAttr != null) 29 | { 30 | UriParameters.Add(uriAttr.Name, property); 31 | Properties.Add(property, uriAttr.Name); 32 | } 33 | } 34 | } 35 | 36 | public ControlSettingsManager(bool isEncrypted = false) 37 | { 38 | _isEncrypted = isEncrypted; 39 | } 40 | 41 | public IDictionary Serialize(ControlSettings settings) 42 | { 43 | var activeSettings = new Dictionary(); 44 | if (settings == null) 45 | { 46 | return activeSettings; 47 | } 48 | 49 | foreach(var settingsInfo in Properties) 50 | { 51 | var property = settingsInfo.Key; 52 | var value = property.GetValue(settings, null); 53 | 54 | if (value == null) 55 | { 56 | continue; 57 | } 58 | 59 | var uriKey = settingsInfo.Value; 60 | string serializedSetting; 61 | if (property.PropertyType == typeof (Color?)) 62 | { 63 | serializedSetting = ((Color?) value).Value 64 | .ToArgb() 65 | .ToString(CultureInfo.CurrentCulture); 66 | } 67 | else 68 | { 69 | serializedSetting = value.ToString(); 70 | } 71 | 72 | activeSettings.Add(uriKey, serializedSetting); 73 | } 74 | 75 | return activeSettings; 76 | } 77 | 78 | public bool IsControlSetting(string key) 79 | { 80 | return UriParameters.ContainsKey(key); 81 | } 82 | 83 | public ControlSettings Deserialize(NameValueCollection queryString) 84 | { 85 | var settings = new ControlSettings(); 86 | if (queryString == null) 87 | { 88 | return settings; 89 | } 90 | 91 | var actualSettings = queryString.AllKeys.Where(IsControlSetting); 92 | foreach (var setting in actualSettings) 93 | { 94 | var property = UriParameters[setting]; 95 | var value = queryString[setting]; 96 | if (_isEncrypted) 97 | { 98 | value = SecurityUtil.Decrypt(value); 99 | } 100 | 101 | DeserializeValue(settings, property, value); 102 | } 103 | 104 | return settings; 105 | } 106 | 107 | private void DeserializeValue(ControlSettings settings, PropertyInfo property, string value) 108 | { 109 | if (string.IsNullOrEmpty(value)) 110 | { 111 | return; 112 | } 113 | 114 | if (property.PropertyType == typeof (string)) 115 | { 116 | property.SetValue(settings, value, null); 117 | } 118 | else if (property.PropertyType == typeof (int?)) 119 | { 120 | int numValue; 121 | if (int.TryParse(value, out numValue)) 122 | { 123 | property.SetValue(settings, numValue, null); 124 | } 125 | } 126 | else if (property.PropertyType == typeof (bool?)) 127 | { 128 | bool boolValue; 129 | if (bool.TryParse(value, out boolValue)) 130 | { 131 | property.SetValue(settings, boolValue, null); 132 | } 133 | } 134 | else if (property.PropertyType == typeof (Color?)) 135 | { 136 | int argbColor; 137 | if (int.TryParse(value, out argbColor)) 138 | { 139 | var color = Color.FromArgb(argbColor); 140 | property.SetValue(settings, color, null); 141 | } 142 | } 143 | else if (property.PropertyType == typeof (Unit?)) 144 | { 145 | var unit = new Unit(value); 146 | property.SetValue(settings, unit, null); 147 | } 148 | else if (property.PropertyType == typeof (BorderStyle?)) 149 | { 150 | BorderStyle style; 151 | if (Enum.TryParse(value, true, out style)) 152 | { 153 | property.SetValue(settings, style, null); 154 | } 155 | } 156 | else if (property.PropertyType == typeof (ZoomMode?)) 157 | { 158 | ZoomMode mode; 159 | if (Enum.TryParse(value, true, out mode)) 160 | { 161 | property.SetValue(settings, mode, null); 162 | } 163 | } 164 | else 165 | { 166 | throw new ArgumentException( 167 | string.Format("Unknown property {0} type: {1}", property.Name, property.PropertyType)); 168 | } 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /MvcReportViewer/ILocalReportDataSourceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.Reporting.WebForms; 4 | 5 | namespace MvcReportViewer 6 | { 7 | /// 8 | /// Interface which stores data sources for Local Report (.rdlc) 9 | /// 10 | public interface ILocalReportDataSourceProvider 11 | { 12 | /// 13 | /// Saves report custom data source, e.g. SQL query, etc. 14 | /// 15 | /// Internal MvcReportViewer instance ID. 16 | /// Data Source Name. 17 | /// Custom Data Source. 18 | void Add(Guid reportControlId, string dataSourceName, T dataSource); 19 | 20 | /// 21 | /// Gets data sources used for the report. 22 | /// 23 | /// Internal MvcReportViewer instance ID. 24 | /// The list of data sources. 25 | IEnumerable Get(Guid reportControlId); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MvcReportViewer/IMvcReportViewerOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Web; 4 | using System.Web.Mvc; 5 | using Microsoft.Reporting.WebForms; 6 | 7 | namespace MvcReportViewer 8 | { 9 | public interface IMvcReportViewerOptions : IHtmlString 10 | { 11 | /// 12 | /// Sets the path to the report on the server. 13 | /// 14 | /// The path to the report on the server. 15 | /// An instance of MvcViewerOptions class. 16 | IMvcReportViewerOptions ReportPath(string reportPath); 17 | 18 | /// 19 | /// Sets the URL for the report server. 20 | /// 21 | /// The URL for the report server. 22 | /// An instance of MvcViewerOptions class. 23 | IMvcReportViewerOptions ReportServerUrl(string reportServerUrl); 24 | 25 | /// 26 | /// Sets the report server username. 27 | /// 28 | /// The report server username. 29 | /// An instance of MvcViewerOptions class. 30 | IMvcReportViewerOptions Username(string username); 31 | 32 | /// 33 | /// Sets the report server password. 34 | /// 35 | /// The report server password. 36 | /// An instance of MvcViewerOptions class. 37 | IMvcReportViewerOptions Password(string password); 38 | 39 | /// 40 | /// Sets the report parameter properties for the report. 41 | /// 42 | /// The report parameter properties for the report. 43 | /// An instance of MvcViewerOptions class. 44 | IMvcReportViewerOptions ReportParameters(object reportParameters); 45 | 46 | /// 47 | /// Sets the report parameter properties for the report. 48 | /// 49 | /// The report parameter properties for the report. 50 | /// An instance of MvcViewerOptions class. 51 | IMvcReportViewerOptions ReportParameters(IEnumerable> reportParameters); 52 | 53 | /// 54 | /// Sets the report parameter properties for the report. 55 | /// 56 | /// The report parameter properties for the report. 57 | /// An instance of MvcViewerOptions class. 58 | IMvcReportViewerOptions ReportParameters(IEnumerable reportParameters); 59 | 60 | /// 61 | /// Sets an object that contains the HTML attributes to set for the element. 62 | /// 63 | /// An object that contains the HTML attributes to set for the element. 64 | /// An instance of MvcViewerOptions class. 65 | IMvcReportViewerOptions Attributes(object htmlAttributes); 66 | 67 | /// 68 | /// Sets the method for sending parameters to the iframe, either GET or POST. 69 | /// POST should be used to send long arguments, etc. Use GET otherwise. 70 | /// 71 | /// The HTTP method for sending parametes to the iframe, either GET or POST. 72 | /// An instance of MvcViewerOptions class. 73 | IMvcReportViewerOptions Method(FormMethod method); 74 | 75 | /// 76 | /// Sets ReportViewer control UI parameters. 77 | /// 78 | /// 79 | /// An instance of MvcViewerOptions class. 80 | IMvcReportViewerOptions ControlSettings(ControlSettings settings); 81 | 82 | /// 83 | /// Sets ReportViewer report processing mode. 84 | /// 85 | /// Processing Mode (Local or Remote). 86 | /// An instance of MvcViewerOptions class. 87 | IMvcReportViewerOptions ProcessingMode(ProcessingMode mode); 88 | 89 | /// 90 | /// Registers custom local data source, e.g. SQL query 91 | /// 92 | /// Report data source name. 93 | /// The data. 94 | /// 95 | IMvcReportViewerOptions LocalDataSource(string dataSourceName, T dataSource); 96 | 97 | /// 98 | /// Sets the type implementing IReportViewerEventsHandler interface. The instance of the type is responsible for 99 | /// processing Report Viewer Web Control's events, e.g. SubreportProcessing. 100 | /// 101 | /// 102 | /// 103 | IMvcReportViewerOptions EventsHandlerType(Type type); 104 | 105 | /// 106 | /// Sets data source credentials for the report. 107 | /// 108 | /// An array of Credentials objects. 109 | /// 110 | IMvcReportViewerOptions SetDataSourceCredentials(DataSourceCredentials[] credentials); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /MvcReportViewer/IReportViewerEventsHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Reporting.WebForms; 2 | 3 | namespace MvcReportViewer 4 | { 5 | public interface IReportViewerEventsHandler 6 | { 7 | void OnSubreportProcessing(ReportViewer reportViewer, SubreportProcessingEventArgs e); 8 | 9 | void OnDrillthrough(ReportViewer reportViewer, DrillthroughEventArgs e); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MvcReportViewer/IgnoreCaseExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Specialized; 3 | using System.Linq; 4 | 5 | namespace MvcReportViewer 6 | { 7 | internal static class IgnoreCaseExtensions 8 | { 9 | public static bool EqualsIgnoreCase(this string that, string str) 10 | { 11 | return string.Compare(that, str, StringComparison.OrdinalIgnoreCase) == 0; 12 | } 13 | 14 | public static bool ContainsKeyIgnoreCase(this NameValueCollection collection, string key) 15 | { 16 | return collection.AllKeys.Any(k => k.EqualsIgnoreCase(key)); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MvcReportViewer/LocalReportDataSourceProviderFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using MvcReportViewer.Configuration; 4 | 5 | namespace MvcReportViewer 6 | { 7 | public class LocalReportDataSourceProviderFactory 8 | { 9 | private static readonly object SyncRoot = new object(); 10 | 11 | private static LocalReportDataSourceProviderFactory _factory; 12 | 13 | private readonly ReportViewerConfiguration _config = new ReportViewerConfiguration(); 14 | 15 | public static LocalReportDataSourceProviderFactory Current 16 | { 17 | get 18 | { 19 | if (_factory != null) 20 | { 21 | return _factory; 22 | } 23 | 24 | var resolver = DependencyResolver.Current; 25 | lock(SyncRoot) 26 | { 27 | _factory = resolver.GetService() ?? 28 | new LocalReportDataSourceProviderFactory(); 29 | } 30 | 31 | return _factory; 32 | } 33 | } 34 | 35 | public virtual ILocalReportDataSourceProvider Create() 36 | { 37 | var resolver = DependencyResolver.Current; 38 | var provider = resolver.GetService(); 39 | if (provider != null) 40 | { 41 | return provider; 42 | } 43 | 44 | // Try to get data source provider from database settings 45 | 46 | var providerTypeName = _config.LocalDataSourceProvider; 47 | if (string.IsNullOrEmpty(providerTypeName)) 48 | { 49 | throw new MvcReportViewerException("Local Data Source Provider configuration is not found in the Web.config"); 50 | } 51 | 52 | try 53 | { 54 | var providerType = Type.GetType(providerTypeName); 55 | if (providerType == null) 56 | { 57 | throw new InvalidOperationException($"Cannot find {providerTypeName} type"); 58 | } 59 | 60 | provider = (ILocalReportDataSourceProvider)Activator.CreateInstance(providerType); 61 | 62 | return provider; 63 | } 64 | catch (Exception err) 65 | { 66 | throw new MvcReportViewerException( 67 | "Local Data Source Provider configuration is not found in the Web.config", 68 | err); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MvcReportViewer/MvcReportViewer.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" AutoEventWireup="true" Inherits="MvcReportViewer.MvcReportViewer, MvcReportViewer" %> 2 | <%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 16 | 17 |
18 |
19 | 20 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /MvcReportViewer/MvcReportViewer.aspx.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Reporting.WebForms; 2 | using System; 3 | using System.Web; 4 | using System.Web.UI; 5 | using MvcReportViewer.Configuration; 6 | 7 | namespace MvcReportViewer 8 | { 9 | /// 10 | /// MvcReportViewer.aspx implementation. The page renders a report. 11 | /// 12 | public class MvcReportViewer : Page 13 | { 14 | private const string IsHeightChangedJs = ""; 15 | private const string ShowPrintButtonJs = ""; 16 | 17 | private const string EventHandlers = "MvcReportViewer.EventHandlers"; 18 | 19 | private readonly ReportViewerConfiguration _config = new ReportViewerConfiguration(); 20 | 21 | protected ReportViewer ReportViewer; 22 | 23 | protected ScriptManager ScriptManager; 24 | 25 | protected void Page_Load(object sender, EventArgs e) 26 | { 27 | ShowReport(); 28 | } 29 | 30 | private void ShowReport() 31 | { 32 | try 33 | { 34 | if (!IsPostBack) 35 | { 36 | var parser = new ReportViewerParametersParser(); 37 | var parameters = Request.Form.Count > 0 ? parser.Parse(Request.Form) : parser.Parse(Request.QueryString); 38 | 39 | var hasHeightChangedScript = string.Format( 40 | IsHeightChangedJs, 41 | parameters.ControlSettings.Height == null ? "false" : "true"); 42 | ClientScript.RegisterStartupScript(GetType(), "IsHeightChangedJS", hasHeightChangedScript); 43 | 44 | var showPrintButtonScript = string.Format(ShowPrintButtonJs, 45 | parameters.ControlSettings.ShowPrintButton == false ? "false" : "true"); 46 | ClientScript.RegisterStartupScript(GetType(), "ShowPrintButtonJs", showPrintButtonScript); 47 | 48 | ReportViewer.ReportError += OnReportError; 49 | ReportViewer.Initialize(parameters); 50 | 51 | RegisterJavaScriptApi(parameters); 52 | 53 | // Save Drillthrough information for future use 54 | if (!string.IsNullOrEmpty(parameters.EventsHandlerType)) 55 | { 56 | ViewState[EventHandlers] = parameters.EventsHandlerType; 57 | } 58 | } 59 | else 60 | { 61 | // Drillthrough event has to be configured no matter what. 62 | var eventHandlers = ViewState[EventHandlers] as string; 63 | if (!string.IsNullOrEmpty(eventHandlers)) 64 | { 65 | ReportViewer.SetupDrillthrough(eventHandlers); 66 | } 67 | } 68 | } 69 | catch (Exception e) 70 | { 71 | var result = RedirectToErrorPage(e); 72 | if (!result) 73 | { 74 | throw; 75 | } 76 | } 77 | } 78 | 79 | private void OnReportError(object sender, ReportErrorEventArgs e) 80 | { 81 | RedirectToErrorPage(e.Exception); 82 | e.Handled = true; 83 | } 84 | 85 | private void RegisterJavaScriptApi(ReportViewerParameters parameters) 86 | { 87 | if (parameters.ControlSettings.AsyncPostBackTimeout != null) 88 | { 89 | ScriptManager.AsyncPostBackTimeout = (int)parameters.ControlSettings.AsyncPostBackTimeout; 90 | } 91 | 92 | var javaScriptApi = _config.AspxViewerJavaScript; 93 | if (string.IsNullOrEmpty(javaScriptApi)) 94 | { 95 | throw new MvcReportViewerException("MvcReportViewer.js location is not found. Make sure you have MvcReportViewer.AspxViewerJavaScript in your Web.config."); 96 | } 97 | 98 | if (javaScriptApi.StartsWith("~")) 99 | { 100 | javaScriptApi = VirtualPathUtility.ToAbsolute(javaScriptApi); 101 | } 102 | 103 | ClientScript.RegisterClientScriptInclude("JavaScriptAPI", javaScriptApi); 104 | } 105 | 106 | private bool RedirectToErrorPage(Exception exception) 107 | { 108 | Trace.Warn("MvcReportViewer", exception.Message); 109 | 110 | var errorPage = _config.ErrorPage; 111 | if (!_config.ShowErrorPage || string.IsNullOrEmpty(errorPage)) 112 | { 113 | return false; 114 | } 115 | 116 | var errorUrl = $"{errorPage}?error={Server.UrlEncode(exception.Message)}&errorType={Server.UrlEncode(exception.GetType().FullName)}"; 117 | 118 | Response.Redirect(errorUrl); 119 | return true; 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /MvcReportViewer/MvcReportViewer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6353720D-C784-4C00-A7B7-D652542FBCC9} 8 | Library 9 | Properties 10 | MvcReportViewer 11 | MvcReportViewer 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | True 37 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 38 | 39 | 40 | ..\packages\Newtonsoft.Json.8.0.2\lib\net40\Newtonsoft.Json.dll 41 | True 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | True 51 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll 52 | 53 | 54 | True 55 | ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll 56 | 57 | 58 | True 59 | ..\packages\Microsoft.AspNet.Razor.2.0.20710.0\lib\net40\System.Web.Razor.dll 60 | 61 | 62 | True 63 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll 64 | 65 | 66 | True 67 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll 68 | 69 | 70 | True 71 | ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | MvcReportViewer.aspx 91 | ASPXCodeBehind 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | Always 114 | ASPXCodeBehind 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 132 | -------------------------------------------------------------------------------- /MvcReportViewer/MvcReportViewerException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcReportViewer 4 | { 5 | /// 6 | /// Generic MvcReportViewer exception. 7 | /// 8 | public class MvcReportViewerException : Exception 9 | { 10 | /// 11 | /// Initializes a new instance of the MvcReportViewerException class with a specified error message. 12 | /// 13 | /// The message that describes the error. 14 | public MvcReportViewerException(string message) 15 | : base(message) 16 | { 17 | } 18 | 19 | /// 20 | /// Initializes a new instance of the MvcReportViewerException class with a specified error message and a reference to the inner exception that is the cause of this exception. 21 | /// 22 | /// The error message that explains the reason for the exception. 23 | /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified. 24 | public MvcReportViewerException(string message, Exception innerException) 25 | : base(message, innerException) 26 | { 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MvcReportViewer/MvcReportViewerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Web.Mvc; 4 | 5 | namespace MvcReportViewer 6 | { 7 | /// 8 | /// HTML helpers for MvcReportViewer. 9 | /// 10 | public static class MvcReportViewerExtensions 11 | { 12 | /// 13 | /// Returns an HTML iframe rendering ASP.NET ReportViewer control with Remote Processing Mode. 14 | /// 15 | /// The HTML helper instance that this method extends. 16 | /// The path to the report on the server. 17 | /// An object that contains the HTML attributes to set for the element. 18 | /// An HTML iframe element. 19 | public static MvcReportViewerIframe MvcReportViewer( 20 | this HtmlHelper helper, 21 | string reportPath, 22 | object htmlAttributes) 23 | { 24 | return new MvcReportViewerIframe( 25 | reportPath, 26 | HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 27 | } 28 | 29 | /// 30 | /// Returns an HTML iframe rendering ASP.NET ReportViewer control with Remote Processing Mode. 31 | /// 32 | /// The HTML helper instance that this method extends. 33 | /// The path to the report on the server. 34 | /// The report parameter properties for the report. 35 | /// An object that contains the HTML attributes to set for the element. 36 | /// An HTML iframe element. 37 | public static MvcReportViewerIframe MvcReportViewer( 38 | this HtmlHelper helper, 39 | string reportPath, 40 | object reportParameters, 41 | object htmlAttributes) 42 | { 43 | return new MvcReportViewerIframe( 44 | reportPath, 45 | HtmlHelper.AnonymousObjectToHtmlAttributes(reportParameters), 46 | HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 47 | } 48 | 49 | /// 50 | /// Returns an HTML iframe rendering ASP.NET ReportViewer control with Remote Processing Mode. 51 | /// 52 | /// The HTML helper instance that this method extends. 53 | /// The path to the report on the server. 54 | /// The report parameter properties for the report. 55 | /// An object that contains the HTML attributes to set for the element. 56 | /// An HTML iframe element. 57 | public static MvcReportViewerIframe MvcReportViewer( 58 | this HtmlHelper helper, 59 | string reportPath, 60 | IEnumerable> reportParameters, 61 | object htmlAttributes) 62 | { 63 | return new MvcReportViewerIframe( 64 | reportPath, 65 | reportParameters, 66 | HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); 67 | } 68 | 69 | /// 70 | /// Returns an HTML iframe rendering ASP.NET ReportViewer control with Remote Processing Mode. 71 | /// 72 | /// The HTML helper instance that this method extends. 73 | /// The path to the report on the server. 74 | /// The URL for the report server. 75 | /// The report server username. 76 | /// The report server password. 77 | /// The report parameter properties for the report. 78 | /// The Report Viewer control's UI settings. 79 | /// An object that contains the HTML attributes to set for the element. 80 | /// Method for sending parameters to the iframe, either GET or POST. 81 | /// An HTML iframe element. 82 | public static MvcReportViewerIframe MvcReportViewer( 83 | this HtmlHelper helper, 84 | string reportPath, 85 | string reportServerUrl = null, 86 | string username = null, 87 | string password = null, 88 | IEnumerable> reportParameters = null, 89 | ControlSettings controlSettings = null, 90 | object htmlAttributes = null, 91 | FormMethod method = FormMethod.Get) 92 | { 93 | return new MvcReportViewerIframe( 94 | reportPath, 95 | reportServerUrl, 96 | username, 97 | password, 98 | reportParameters, 99 | controlSettings, 100 | HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), 101 | method); 102 | } 103 | 104 | /// 105 | /// Returns fluent interface to HTML iframe rendering ASP.NET ReportViewer control. 106 | /// 107 | /// The HTML helper instance that this method extends. 108 | /// The path to the report on the server. 109 | /// Fluent interface HTML iframe element. 110 | public static IMvcReportViewerOptions MvcReportViewerFluent( 111 | this HtmlHelper helper, 112 | string reportPath) 113 | { 114 | return new MvcReportViewerIframe(reportPath); 115 | } 116 | 117 | /// 118 | /// Returns fluent interface to HTML iframe rendering ASP.NET ReportViewer control. 119 | /// IMPORTANT: Unit-tests only! 120 | /// 121 | /// The HTML helper instance that this method extends. 122 | /// The path to the report on the server. 123 | /// MvcReportViewer control ID 124 | /// Fluent interface HTML iframe element. 125 | internal static IMvcReportViewerOptions MvcReportViewerFluent( 126 | this HtmlHelper helper, 127 | string reportPath, 128 | Guid controlId) 129 | { 130 | var iframe = new MvcReportViewerIframe(reportPath) {ControlId = controlId}; 131 | return iframe; 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /MvcReportViewer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MvcReportViewer")] 9 | [assembly: AssemblyDescription("ASP.NET MVC wrapped for Microsoft ReportViewer control")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MvcReportViewer")] 13 | [assembly: AssemblyCopyright("Copyright © Ilya Verbitskiy 2013-2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3c768ca3-9002-4782-8e24-3dbd5b5c858f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.8.*")] 36 | [assembly: AssemblyFileVersion("0.8.3.0")] 37 | [assembly: InternalsVisibleTo("MvcReportViewerTests")] 38 | -------------------------------------------------------------------------------- /MvcReportViewer/ReportFormat.cs: -------------------------------------------------------------------------------- 1 | namespace MvcReportViewer 2 | { 3 | public enum ReportFormat 4 | { 5 | Excel, 6 | Word, 7 | Pdf, 8 | Image, 9 | ExcelOpenXml, 10 | WordOpenXml, 11 | MHtml, 12 | Atom, 13 | Rgdi, 14 | Rpl, 15 | Html 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MvcReportViewer/ReportServerCredentials.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Reporting.WebForms; 3 | using System.Net; 4 | using System.Security.Principal; 5 | 6 | namespace MvcReportViewer 7 | { 8 | [Serializable] 9 | internal class ReportServerCredentials : IReportServerCredentials 10 | { 11 | private readonly string _username; 12 | 13 | private readonly string _password; 14 | 15 | public ReportServerCredentials(string username, string password) 16 | { 17 | _username = username; 18 | _password = password; 19 | } 20 | 21 | public WindowsIdentity ImpersonationUser => null; 22 | 23 | public ICredentials NetworkCredentials => new NetworkCredential(_username, _password); 24 | 25 | public bool GetFormsCredentials(out Cookie authCookie, out string userName, out string password, out string authority) 26 | { 27 | authCookie = null; 28 | userName = null; 29 | password = null; 30 | authority = null; 31 | return false; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MvcReportViewer/ReportViewerParameters.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Reporting.WebForms; 2 | using System.Collections.Generic; 3 | using System; 4 | using System.Data; 5 | 6 | namespace MvcReportViewer 7 | { 8 | internal class ReportViewerParameters 9 | { 10 | public ReportViewerParameters() 11 | { 12 | ReportParameters = new Dictionary(); 13 | } 14 | 15 | public string ReportServerUrl { get; set; } 16 | 17 | public string Username { get; set; } 18 | 19 | public string Password { get; set; } 20 | 21 | public string ReportPath { get; set; } 22 | 23 | public Guid? ControlId { get; set; } 24 | 25 | public ProcessingMode ProcessingMode { get; set; } 26 | 27 | public bool IsAzureSsrs { get; set; } 28 | 29 | public IDictionary ReportParameters { get; set; } 30 | 31 | public IDictionary LocalReportDataSources { get; set; } 32 | 33 | public DataSourceCredentials[] DataSourceCredentials { get; set; } 34 | 35 | public bool IsReportRunnerExecution { get; set; } 36 | 37 | public ControlSettings ControlSettings { get; set; } 38 | 39 | public string EventsHandlerType { get; set; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MvcReportViewer/ReportViewerParametersParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Specialized; 3 | using Microsoft.Reporting.WebForms; 4 | using System.Web; 5 | using MvcReportViewer.Configuration; 6 | using Newtonsoft.Json; 7 | 8 | namespace MvcReportViewer 9 | { 10 | internal class ReportViewerParametersParser 11 | { 12 | private static readonly ReportViewerConfiguration Config = new ReportViewerConfiguration(); 13 | 14 | public ReportViewerParameters Parse(NameValueCollection queryString) 15 | { 16 | if (queryString == null) 17 | { 18 | throw new ArgumentNullException(nameof(queryString)); 19 | } 20 | 21 | var isEncrypted = CheckEncryption(ref queryString); 22 | 23 | var settinsManager = new ControlSettingsManager(isEncrypted); 24 | 25 | var parameters = InitializeDefaults(); 26 | ResetDefaultCredentials(queryString, parameters); 27 | parameters.ControlSettings = settinsManager.Deserialize(queryString); 28 | 29 | foreach (var key in queryString.AllKeys) 30 | { 31 | var urlParam = queryString[key]; 32 | if (key.EqualsIgnoreCase(UriParameters.ReportPath)) 33 | { 34 | parameters.ReportPath = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 35 | } 36 | else if (key.EqualsIgnoreCase(UriParameters.ControlId)) 37 | { 38 | var parameter = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 39 | parameters.ControlId = Guid.Parse(parameter); 40 | } 41 | else if (key.EqualsIgnoreCase(UriParameters.ProcessingMode)) 42 | { 43 | var parameter = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 44 | parameters.ProcessingMode = (ProcessingMode)Enum.Parse(typeof(ProcessingMode), parameter); 45 | } 46 | else if (key.EqualsIgnoreCase(UriParameters.ReportServerUrl)) 47 | { 48 | parameters.ReportServerUrl = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 49 | } 50 | else if (key.EqualsIgnoreCase(UriParameters.Username)) 51 | { 52 | parameters.Username = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 53 | } 54 | else if (key.EqualsIgnoreCase(UriParameters.Password)) 55 | { 56 | parameters.Password = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 57 | } 58 | else if (key.EqualsIgnoreCase(UriParameters.EventsHandlerType)) 59 | { 60 | parameters.EventsHandlerType = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 61 | } 62 | else if (key.EqualsIgnoreCase(UriParameters.DataSourceCredentials)) 63 | { 64 | var json = isEncrypted ? SecurityUtil.Decrypt(urlParam) : urlParam; 65 | parameters.DataSourceCredentials = JsonConvert.DeserializeObject(json); 66 | } 67 | else if (!settinsManager.IsControlSetting(key)) 68 | { 69 | var values = queryString.GetValues(key); 70 | if (values != null) 71 | { 72 | foreach (var value in values) 73 | { 74 | var realValue = isEncrypted ? SecurityUtil.Decrypt(value) : value; 75 | var parsedKey = ParseKey(key); 76 | var realKey = parsedKey.Item1; 77 | var isVisible = parsedKey.Item2; 78 | 79 | if (parameters.ReportParameters.ContainsKey(realKey)) 80 | { 81 | parameters.ReportParameters[realKey].Values.Add(realValue); 82 | } 83 | else 84 | { 85 | var reportParameter = new ReportParameter(realKey) {Visible = isVisible}; 86 | reportParameter.Values.Add(realValue); 87 | parameters.ReportParameters.Add(realKey, reportParameter); 88 | } 89 | } 90 | } 91 | } 92 | } 93 | 94 | if (parameters.ProcessingMode == ProcessingMode.Remote 95 | && string.IsNullOrEmpty(parameters.ReportServerUrl)) 96 | { 97 | throw new MvcReportViewerException("Report Server is not specified."); 98 | } 99 | 100 | if (string.IsNullOrEmpty(parameters.ReportPath)) 101 | { 102 | throw new MvcReportViewerException("Report is not specified."); 103 | } 104 | 105 | return parameters; 106 | } 107 | 108 | private static Tuple ParseKey(string key) 109 | { 110 | if (!key.Contains(MvcReportViewerIframe.VisibilitySeparator)) 111 | { 112 | return new Tuple(key, true); 113 | } 114 | 115 | var parts = key.Split(new[] { MvcReportViewerIframe.VisibilitySeparator }, StringSplitOptions.RemoveEmptyEntries); 116 | bool isVisible; 117 | if (parts.Length != 2 || !bool.TryParse(parts[1], out isVisible)) 118 | { 119 | return new Tuple(key, true); 120 | } 121 | 122 | return new Tuple(parts[0], isVisible); 123 | } 124 | 125 | private static bool CheckEncryption(ref NameValueCollection source) 126 | { 127 | var isEncrypted = Config.EncryptParameters; 128 | 129 | // each parameter is encrypted when POST method is used 130 | if (string.Compare(HttpContext.Current.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase) == 0) 131 | { 132 | return isEncrypted; 133 | } 134 | 135 | if (!isEncrypted) 136 | { 137 | return false; 138 | } 139 | 140 | var encrypted = source[UriParameters.Encrypted]; 141 | var decrypted = SecurityUtil.Decrypt(encrypted); 142 | source = HttpUtility.ParseQueryString(decrypted); 143 | return false; // Return false here because we have already decrypted query string 144 | } 145 | 146 | private static void ResetDefaultCredentials(NameValueCollection queryString, ReportViewerParameters parameters) 147 | { 148 | if (queryString.ContainsKeyIgnoreCase(UriParameters.Username) || 149 | queryString.ContainsKeyIgnoreCase(UriParameters.Password)) 150 | { 151 | parameters.Username = string.Empty; 152 | parameters.Password = string.Empty; 153 | } 154 | } 155 | 156 | private ReportViewerParameters InitializeDefaults() 157 | { 158 | var parameters = new ReportViewerParameters 159 | { 160 | ReportServerUrl = Config.ReportServerUrl, 161 | Username = Config.Username, 162 | Password = Config.Password, 163 | IsAzureSsrs = Config.IsAzureSSRS 164 | }; 165 | 166 | return parameters; 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /MvcReportViewer/SecurityUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Web.Security; 4 | 5 | namespace MvcReportViewer 6 | { 7 | static class SecurityUtil 8 | { 9 | public static string Encrypt(string value) 10 | { 11 | var bytes = Encoding.Unicode.GetBytes(value); 12 | #if NET45 13 | var encryptedBytes = MachineKey.Protect(bytes); 14 | var encrypted = BitConverter.ToString(encryptedBytes).Replace("-", ""); 15 | #else 16 | var encrypted = MachineKey.Encode(bytes, MachineKeyProtection.Encryption); 17 | #endif 18 | return encrypted; 19 | } 20 | 21 | public static string Decrypt(string encrypted) 22 | { 23 | #if NET45 24 | var encryptedBytes = Hex2Bytes(encrypted); 25 | var bytes = MachineKey.Unprotect(encryptedBytes); 26 | #else 27 | var bytes = MachineKey.Decode(encrypted, MachineKeyProtection.Encryption); 28 | #endif 29 | if (bytes == null) 30 | { 31 | throw new InvalidOperationException("Data cannot be decrypted using Machine Key"); 32 | } 33 | 34 | var value = Encoding.Unicode.GetString(bytes); 35 | return value; 36 | } 37 | 38 | private static byte[] Hex2Bytes(string hex) 39 | { 40 | if (hex.Length % 2 != 0) 41 | { 42 | throw new ArgumentException(hex); 43 | } 44 | 45 | var bytes = new byte[hex.Length / 2]; 46 | for(var i = 0; i < hex.Length; i += 2) 47 | { 48 | var encByte = hex.Substring(i, 2); 49 | bytes[i / 2] = Convert.ToByte(encByte, 16); 50 | } 51 | 52 | return bytes; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /MvcReportViewer/SessionLocalDataSourceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.SessionState; 7 | using Microsoft.Reporting.WebForms; 8 | 9 | namespace MvcReportViewer 10 | { 11 | public class SessionLocalDataSourceProvider : BaseLocalDataSourceProvider, ILocalReportDataSourceProvider 12 | { 13 | private readonly HttpSessionState _session = HttpContext.Current.Session; 14 | 15 | public void Add(Guid reportControlId, string dataSourceName, T dataSource) 16 | { 17 | var source = dataSource as ReportDataSource ?? new ReportDataSource(dataSourceName, dataSource); 18 | 19 | if (dataSource == null) 20 | { 21 | return; 22 | } 23 | 24 | var key = GetSessionValueKey(reportControlId); 25 | var dataSources = _session[key] as List; 26 | dataSources = dataSources ?? new List(); 27 | 28 | dataSources.Add( 29 | new ReportDataSourceWrapper 30 | { 31 | Name = source.Name, 32 | Value = source.Value 33 | }); 34 | 35 | _session[key] = dataSources; 36 | } 37 | 38 | public IEnumerable Get(Guid reportControlId) 39 | { 40 | var key = GetSessionValueKey(reportControlId); 41 | var dataSources = _session[key] as List; 42 | return dataSources?.Select(s => new ReportDataSource(s.Name, s.Value)) ?? new List(); 43 | } 44 | 45 | [Serializable] 46 | private class ReportDataSourceWrapper 47 | { 48 | public string Name { get; set; } 49 | 50 | public object Value { get; set; } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MvcReportViewer/SqlLocalDataSourceProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Data.Common; 6 | using System.Web; 7 | using System.Web.SessionState; 8 | using Microsoft.Reporting.WebForms; 9 | 10 | namespace MvcReportViewer 11 | { 12 | public class SqlLocalDataSourceProvider : BaseLocalDataSourceProvider, ILocalReportDataSourceProvider 13 | { 14 | private static readonly string Config = "SqlLocalDataSourceProvider.ConnectionString"; 15 | 16 | private readonly HttpSessionState _session = HttpContext.Current.Session; 17 | 18 | public void Add(Guid reportControlId, string dataSourceName, T dataSource) 19 | { 20 | // This local report data source provider works only with string 21 | // parameters which are SQL queries 22 | if (!(dataSource is string)) 23 | { 24 | throw new InvalidOperationException("SqlLocalDataSourceProvider supports only SQL queries (string)"); 25 | } 26 | 27 | var key = GetSessionValueKey(reportControlId); 28 | var dataSources = _session[key] as List; 29 | dataSources = dataSources ?? new List(); 30 | 31 | dataSources.Add( 32 | new SqlDataSource 33 | { 34 | Name = dataSourceName, 35 | Query = dataSource.ToString() 36 | }); 37 | 38 | _session[key] = dataSources; 39 | } 40 | 41 | public IEnumerable Get(Guid reportControlId) 42 | { 43 | var key = GetSessionValueKey(reportControlId); 44 | var queries = _session[key] as List; 45 | 46 | var dataSources = new List(); 47 | if (queries == null || queries.Count == 0) 48 | { 49 | return dataSources; 50 | } 51 | 52 | var connectionString = GetConnectionString(); 53 | var dbProviderFactory = DbProviderFactories.GetFactory(connectionString.ProviderName); 54 | using (var connection = dbProviderFactory.CreateConnection()) 55 | { 56 | if (connection == null) 57 | { 58 | throw new InvalidOperationException(connectionString.ProviderName); 59 | } 60 | 61 | connection.ConnectionString = connectionString.ConnectionString; 62 | 63 | foreach (var query in queries) 64 | { 65 | using (var command = connection.CreateCommand()) 66 | { 67 | command.CommandText = query.Query; 68 | 69 | using (var adapter = dbProviderFactory.CreateDataAdapter()) 70 | { 71 | if (adapter == null) 72 | { 73 | throw new InvalidOperationException("Cannot create Data Adapter for " + connectionString.ProviderName); 74 | } 75 | 76 | adapter.SelectCommand = command; 77 | 78 | var table = new DataTable(); 79 | adapter.Fill(table); 80 | dataSources.Add(new ReportDataSource(query.Name, table)); 81 | } 82 | } 83 | } 84 | } 85 | 86 | return dataSources; 87 | } 88 | 89 | private ConnectionStringSettings GetConnectionString() 90 | { 91 | var connectionStringName = ConfigurationManager.AppSettings[Config]; 92 | if (string.IsNullOrEmpty(connectionStringName)) 93 | { 94 | throw new InvalidOperationException(Config + " is not set in application configuration file"); 95 | } 96 | 97 | var connectionString = ConfigurationManager.ConnectionStrings[connectionStringName]; 98 | return connectionString; 99 | } 100 | 101 | [Serializable] 102 | private class SqlDataSource 103 | { 104 | public string Name { get; set; } 105 | 106 | public string Query { get; set; } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /MvcReportViewer/UriParameterAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MvcReportViewer 4 | { 5 | [AttributeUsage(AttributeTargets.Property)] 6 | internal class UriParameterAttribute : Attribute 7 | { 8 | public UriParameterAttribute(string name) 9 | { 10 | Name = name; 11 | } 12 | 13 | public string Name { get; private set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /MvcReportViewer/UriParameters.cs: -------------------------------------------------------------------------------- 1 | namespace MvcReportViewer 2 | { 3 | internal static class UriParameters 4 | { 5 | public static readonly string ReportServerUrl = "_s"; 6 | 7 | public static readonly string ReportPath = "_r"; 8 | 9 | public static readonly string Username = "_u"; 10 | 11 | public static readonly string Password = "_p"; 12 | 13 | public static readonly string Encrypted = "_e"; 14 | 15 | public static readonly string ControlId = "_id"; 16 | 17 | public static readonly string ProcessingMode = "_m"; 18 | 19 | public static readonly string EventsHandlerType = "_evh"; 20 | 21 | public static readonly string DataSourceCredentials = "_dc"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /MvcReportViewer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MvcReportViewerExample/.gitattributes: -------------------------------------------------------------------------------- 1 | Web.config merge=ours -------------------------------------------------------------------------------- /MvcReportViewerExample/App_Data/Database.mdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilich/MvcReportViewer/9aa174e402d7d924ab1c40bc0bc287bf0ac672a4/MvcReportViewerExample/App_Data/Database.mdf -------------------------------------------------------------------------------- /MvcReportViewerExample/App_Data/Database_log.ldf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ilich/MvcReportViewer/9aa174e402d7d924ab1c40bc0bc287bf0ac672a4/MvcReportViewerExample/App_Data/Database_log.ldf -------------------------------------------------------------------------------- /MvcReportViewerExample/App_Data/Reports/CitiesByCountry.rdlc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 3.8125in 10 | 11 | 12 | 13 | 14 | 0.25in 15 | 16 | 17 | 18 | 19 | true 20 | true 21 | 22 | 23 | 24 | 25 | =Fields!Name.Value 26 | 30 | 31 | 32 | 40 | 41 | 2pt 42 | 2pt 43 | 2pt 44 | 2pt 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | Cities 66 | 0.25in 67 | 3.8125in 68 | 71 | 72 | 73 | 74 | 75 | 0.35416in 76 | 31 | 32 | 33 | 41 | 42 | 2pt 43 | 2pt 44 | 2pt 45 | 2pt 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 0.25in 54 | 55 | 56 | 57 | 58 | CitiesByCountry 59 | 60 | 61 | =Fields!Id.Value 62 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 0.08333in 76 | 77 | 78 | 79 | 80 | true 81 | true 82 | 83 | 84 | 85 | 86 | 87 | 97 | 98 | 99 | Black 100 | 101 | 1pt 102 | 103 | 2pt 104 | 2pt 105 | 2pt 106 | 2pt 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 | Countries 133 | 0.58333in 134 | 4.21875in 135 | 138 | 139 | 140 | 141 | 142 | 3.99875in 143 | 32 | 33 | 34 | 42 | 43 | #4c68a2 44 | 2pt 45 | 2pt 46 | 2pt 47 | 2pt 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 0.25in 56 | 57 | 58 | 59 | 60 | true 61 | true 62 | 63 | 64 | 65 | 66 | =Fields!Name.Value 67 | 71 | 72 | 73 | 95 | 96 | 2pt 97 | 2pt 98 | 2pt 99 | 2pt 100 | 101 | 102 | true 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | After 118 | 119 | 120 | 121 | 122 | 123 | 124 | Countries 125 | 0.5in 126 | 5.34375in 127 | 130 | 131 | 132 | 133 | 134 | 0.91667in 135 | 17 | 18 | 19 | 30 | 31 | 2pt 32 | 2pt 33 | 2pt 34 | 2pt 35 | 36 | 37 | 38 | true 39 | true 40 | 41 | 42 | 43 | 44 | Today: 45 | 48 | 49 | 50 | 62 | 63 | 2pt 64 | 2pt 65 | 2pt 66 | 2pt 67 | 68 | 69 | 70 | true 71 | true 72 | 73 | 74 | 75 | 76 | =Parameters!TodayDate.Value 77 | 92 | 93 | 2pt 94 | 2pt 95 | 2pt 96 | 2pt 97 | 98 | 99 | 100 | 2in 101 |