如何在asp.net mvc 3razor视图中使用reportviewer控件?
我试图在mvc 3框架中使用razor视图中的reportviewer控件。 在线文档谈话的拖放。 任何有关如何将其插入视图的build议。
以下解决scheme仅适用于单页报告。 请参阅评论了解更多详情。
ReportViewer是一个服务器控件,因此不能在razor视图中使用。 但是,您可以添加ASPX视图页面,查看包含ReportViewer的用户控件或传统Web窗体到应用程序中。
你将需要确保你已经添加了相关的处理程序到你的web.config 。
如果您使用ASPX视图页面或查看用户控件,则需要将AsyncRendering设置为false才能使报表正确显示。
更新:
增加了更多示例代码。 请注意,Global.asax中不需要进行有意义的更改。
Web.Config中
我的结果如下:
<?xml version="1.0"?> <!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=152368 --> <configuration> <appSettings> <add key="webpages:Version" value="1.0.0.0"/> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings> <system.web> <compilation debug="true" targetFramework="4.0"> <assemblies> <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" /> <add assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/> <add assembly="Microsoft.ReportViewer.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/> </assemblies> </compilation> <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880" /> </authentication> <pages> <namespaces> <add namespace="System.Web.Helpers" /> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Routing" /> <add namespace="System.Web.WebPages"/> </namespaces> </pages> </system.web> <system.webServer> <validation validateIntegratedModeConfiguration="false"/> <modules runAllManagedModulesForAllRequests="true"/> <handlers> <add name="ReportViewerWebControlHandler" preCondition="integratedMode" verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </handlers> </system.webServer> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
调节器
控制器的操作非常简单。
作为奖励,File()操作将“TestReport.rdlc”的输出作为PDF文件返回。
using System.Web.Mvc; using Microsoft.Reporting.WebForms; ... public class PDFController : Controller { public ActionResult Index() { return View(); } public FileResult File() { ReportViewer rv = new Microsoft.Reporting.WebForms.ReportViewer(); rv.ProcessingMode = ProcessingMode.Local; rv.LocalReport.ReportPath = Server.MapPath("~/Reports/TestReport.rdlc"); rv.LocalReport.Refresh(); byte[] streamBytes = null; string mimeType = ""; string encoding = ""; string filenameExtension = ""; string[] streamids = null; Warning[] warnings = null; streamBytes = rv.LocalReport.Render("PDF", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings); return File(streamBytes, mimeType, "TestReport.pdf"); } public ActionResult ASPXView() { return View(); } public ActionResult ASPXUserControl() { return View(); } }
ASPXView.apsx
ASPXView如下。
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %> <%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %> <!DOCTYPE html> <html> <head runat="server"> <title>ASPXView</title> </head> <body> <div> <script runat="server"> private void Page_Load(object sender, System.EventArgs e) { ReportViewer1.LocalReport.ReportPath = Server.MapPath("~/Reports/TestReport.rdlc"); ReportViewer1.LocalReport.Refresh(); } </script> <form id="Form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <rsweb:reportviewer id="ReportViewer1" runat="server" height="500" width="500" AsyncRendering="false"></rsweb:reportviewer> </form> </div> </body> </html>
ViewUserControl1.ascx
ASPX用户控件看起来像:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %> <script runat="server"> private void Page_Load(object sender, System.EventArgs e) { ReportViewer1.LocalReport.ReportPath = Server.MapPath("~/Reports/TestReport.rdlc"); ReportViewer1.LocalReport.Refresh(); } </script> <form id="Form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <rsweb:ReportViewer ID="ReportViewer1" runat="server" AsyncRendering="false"></rsweb:ReportViewer> </form>
ASPXUserControl.cshtml
剃刀视图。 需要ViewUserControl1.ascx。
@{ ViewBag.Title = "ASPXUserControl"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>ASPXUserControl</h2> @Html.Partial("ViewUserControl1")
参考
在web mvc2中将报告绑定到reportviewer
这是一个简单的任务。 您可以按照以下步骤。
- 在解决scheme中创build一个文件夹并将其命名为Reports 。
- 添加一个ASP.Net Web窗体并将其命名为ReportView.aspx
-
创build一个类ReportData并将其添加到Reports文件夹。 将下面的代码添加到类。
public class ReportData { public ReportData() { this.ReportParameters = new List<Parameter>(); this.DataParameters = new List<Parameter>(); } public bool IsLocal { get; set; } public string ReportName { get; set; } public List<Parameter> ReportParameters { get; set; } public List<Parameter> DataParameters { get; set; } } public class Parameter { public string ParameterName { get; set; } public string Value { get; set; } }
-
添加另一个类并将其命名为ReportBasePage.cs 。 在这个类中添加下面的代码。
public class ReportBasePage : System.Web.UI.Page { protected ReportData ReportDataObj { get; set; } protected override void OnInit(EventArgs e) { base.OnInit(e); if (HttpContext.Current != null) if (HttpContext.Current.Session["ReportData"] != null) { ReportDataObj = HttpContext.Current.Session["ReportData"] as ReportData; return; } ReportDataObj = new ReportData(); CaptureRouteData(Page.Request); } private void CaptureRouteData(HttpRequest request) { var mode = (request.QueryString["rptmode"] + "").Trim(); ReportDataObj.IsLocal = mode == "local" ? true : false; ReportDataObj.ReportName = request.QueryString["reportname"] + ""; string dquerystr = request.QueryString["parameters"] + ""; if (!String.IsNullOrEmpty(dquerystr.Trim())) { var param1 = dquerystr.Split(','); foreach (string pm in param1) { var rp = new Parameter(); var kd = pm.Split('='); if (kd[0].Substring(0, 2) == "rp") { rp.ParameterName = kd[0].Replace("rp", ""); if (kd.Length > 1) rp.Value = kd[1]; ReportDataObj.ReportParameters.Add(rp); } else if (kd[0].Substring(0, 2) == "dp") { rp.ParameterName = kd[0].Replace("dp", ""); if (kd.Length > 1) rp.Value = kd[1]; ReportDataObj.DataParameters.Add(rp); } } } } }
-
将ScriptManager添加到ReportView.aspx页面。 现在将报告查看器添加到页面。 在报告查看器中设置属性AsyncRendering =“false” 。 代码如下。
<rsweb:ReportViewer ID="ReportViewerRSFReports" runat="server" AsyncRendering="false" Width="1271px" Height="1000px" > </rsweb:ReportViewer>
-
在ReportView.aspx.cs中添加两个NameSpace
using Microsoft.Reporting.WebForms; using System.IO;
-
将System.Web.UI.Page更改为ReportBasePage 。 只需使用以下代码replace您的代码。
public partial class ReportView : ReportBasePage { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { RenderReportModels(this.ReportDataObj); } } private void RenderReportModels(ReportData reportData) { // This is the Data Access Layer from which a method is called to fill data to the list. RASolarERPData dal = new RASolarERPData(); List<ClosingInventoryValuation> objClosingInventory = new List<ClosingInventoryValuation>(); // Reset report properties. ReportViewerRSFReports.Height = Unit.Parse("100%"); ReportViewerRSFReports.Width = Unit.Parse("100%"); ReportViewerRSFReports.CssClass = "table"; // Clear out any previous datasources. this.ReportViewerRSFReports.LocalReport.DataSources.Clear(); // Set report mode for local processing. ReportViewerRSFReports.ProcessingMode = ProcessingMode.Local; // Validate report source. var rptPath = Server.MapPath(@"./Report/" + reportData.ReportName +".rdlc"); //@"E:\RSFERP_SourceCode\RASolarERP\RASolarERP\Reports\Report\" + reportData.ReportName + ".rdlc"; //Server.MapPath(@"./Report/ClosingInventory.rdlc"); if (!File.Exists(rptPath)) return; // Set report path. this.ReportViewerRSFReports.LocalReport.ReportPath = rptPath; // Set report parameters. var rpPms = ReportViewerRSFReports.LocalReport.GetParameters(); foreach (var rpm in rpPms) { var p = reportData.ReportParameters.SingleOrDefault(o => o.ParameterName.ToLower() == rpm.Name.ToLower()); if (p != null) { ReportParameter rp = new ReportParameter(rpm.Name, p.Value); ReportViewerRSFReports.LocalReport.SetParameters(rp); } } //Set data paramater for report SP execution objClosingInventory = dal.ClosingInventoryReport(this.ReportDataObj.DataParameters[0].Value); // Load the dataSource. var dsmems = ReportViewerRSFReports.LocalReport.GetDataSourceNames(); ReportViewerRSFReports.LocalReport.DataSources.Add(new ReportDataSource(dsmems[0], objClosingInventory)); // Refresh the ReportViewer. ReportViewerRSFReports.LocalReport.Refresh(); } }
-
将文件夹添加到报告文件夹并将其命名为报告 。 现在将RDLC报告添加到Reports / Report文件夹并将其命名为ClosingInventory.rdlc 。
-
现在添加一个Controller并将其命名为ReportController 。 在控制器中添加以下操作方法。
public ActionResult ReportViewer() { ViewData["reportUrl"] = "../Reports/View/local/ClosingInventory/"; return View(); }
-
点击ReportViewer控制器添加一个视图页面。 将视图页面命名为ReportViewer.cshtml 。 将下面的代码添加到视图页面。
@using (Html.BeginForm("Login")) { @Html.DropDownList("ddlYearMonthFormat", new SelectList(ViewBag.YearMonthFormat, "YearMonthValue", "YearMonthName"), new { @class = "DropDown" }) Stock In Transit: @Html.TextBox("txtStockInTransit", "", new { @class = "LogInTextBox" }) <input type="submit" onclick="return ReportValidationCheck();" name="ShowReport" value="Show Report" /> }
-
添加一个Iframe 。 如下设置Iframe的属性
frameborder="0" width="1000"; height="1000"; style="overflow:hidden;" scrolling="no"
-
将以下JavaScript添加到查看器。
function ReportValidationCheck() { var url = $('#hdUrl').val(); var yearmonth = $('#ddlYearMonthFormat').val(); var stockInTransit = $('#txtStockInTransit').val() if (stockInTransit == "") { stockInTransit = 0; } if (yearmonth == "0") { alert("Please Select Month Correctly."); } else { //url = url + "dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit; url = "../Reports/ReportView.aspx?rptmode=local&reportname=ClosingInventory¶meters=dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit; var myframe = document.getElementById("ifrmReportViewer"); if (myframe !== null) { if (myframe.src) { myframe.src = url; } else if (myframe.contentWindow !== null && myframe.contentWindow.location !== null) { myframe.contentWindow.location = url; } else { myframe.setAttribute('src', url); } } } return false; }
-
Web.config文件将以下密钥添加到appSettings部分
add key="UnobtrusiveJavaScriptEnabled" value="true"
-
在system.web 处理程序部分添加以下键
add verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
-
将您的数据源更改为您自己的。 这个解决scheme非常简单,我想每个人都会喜欢它。
我正在使用SSRS 2008的ASP.NET MVC3,当我尝试从远程服务器获取报告时,我无法使@ Adrian的工作达到100%。
最后,我发现我需要更改ViewUserControl1.ascx中的Page_Load方法,如下所示:
ReportViewer1.ProcessingMode = ProcessingMode.Remote; ServerReport serverReport = ReportViewer1.ServerReport; serverReport.ReportServerUrl = new Uri("http://<Server Name>/reportserver"); serverReport.ReportPath = "/My Folder/MyReport"; serverReport.Refresh();
我一直在错过ProcessingMode.Remote 。
参考文献:
http://msdn.microsoft.com/en-us/library/aa337091.aspx – ReportViewer
这里是一个完整的解决scheme,用于直接在MVC .aspx视图中集成一个报表查看器控件(以及任何asp.net服务器端控件),这个解决scheme也可以在一个包含多个页面的报表上工作(与Adrian Toman的回答不同) AsyncRendering设置为true(基于Steve Sanderson的“Pro ASP.NET MVC Framework”)。
基本上需要做的是:
-
用runat =“server”添加一个表单
-
添加控件(对于报表查看器控件,即使使用AsyncRendering =“True”,有时也可以工作,但并不总是如此,因此请检查您的具体情况)
-
使用runat =“server”脚本标记添加服务器端脚本
-
使用下面显示的代码覆盖Page_Init事件,以启用PostBack和Viewstate的使用
这是一个示范:
<form ID="form1" runat="server"> <rsweb:ReportViewer ID="ReportViewer1" runat="server" /> </form> <script runat="server"> protected void Page_Init(object sender, EventArgs e) { Context.Handler = Page; } //Other code needed for the report viewer here </script>
当然,build议充分利用MVC方法,在控制器中准备所有需要的数据,然后通过ViewModel将其传递给视图。
这将允许重用视图!
然而,这只是对于每次回发所需的数据而言,或者即使只在初始化时需要,如果它不是数据密集型的,并且数据也不依赖于PostBack和ViewState值。
然而,即使是数据密集型的,有时也可以封装成一个lambdaexpression式,然后传递给在那里调用的视图。
一些笔记虽然:
- 通过这样做,这个视图本质上变成了一个带有所有缺点的Web表单(即Postback,以及非Asp.NET控件被覆盖的可能性)
- 重写Page_Init的黑客没有文档logging,随时可能更改
NuGet中有一个MvcReportViewer助手。
http://www.nuget.org/packages/MvcReportViewer/
这就是细节:
https://github.com/ilich/MvcReportViewer
我有使用这个。 它工作很好。
文档是指一个ASP.NET应用程序。
你可以尝试看看我的答案在这里 。
我的回答中有一个例子。
ASP.NET MVC3的另一个例子可以在这里find。
你不但必须使用一个asp.net页面,而且
如果使用entity framework或LinqToSql(如果使用部分类)将数据移动到单独的项目,报表devise器不能看到类。
将报告移动到另一个项目/ DLL,VS10有错误是asp.net项目无法看到Web应用程序中的对象数据源。 然后将来自dll的报告stream入您的mvc项目aspx页面。
这适用于mvc和webform项目。 在本地模式下使用sql报表不是一个令人愉快的开发经验。 如果导出大型报告,也请留意您的networking服务器内存。 报告查看器/导出devise非常糟糕。
可以在不使用iFrame或aspx页面的情况下,将SSRS报告显示在MVC页面上。
大部分工作在这里解释:
该链接解释了如何创build一个Web服务和MVC操作方法,使您可以调用报告服务并将Web服务的结果呈现为Excel文件。 通过对示例中的代码进行小小更改,您可以将其呈现为HTML。
所有你需要做的就是使用一个button来调用一个javascript函数,这个函数会对你的MVC动作进行一次AJAX调用,返回报表的HTML。 当AJAX调用返回的HTML只是用这个HTMLreplace一个div。
我们使用AngularJS,所以我的下面的例子是这种格式,但它可以是任何JavaScript函数
$scope.getReport = function() { $http({ method: "POST", url: "Report/ExportReport", data: [ { Name: 'DateFrom', Value: $scope.dateFrom }, { Name: 'DateTo', Value: $scope.dateTo }, { Name: 'LocationsCSV', Value: $scope.locationCSV } ] }) .success(function (serverData) { $("#ReportDiv").html(serverData); }); };
行动方法 – 主要取自上述链接…
[System.Web.Mvc.HttpPost] public FileContentResult ExportReport([FromBody]List<ReportParameterModel> parameters) { byte[] output; string extension, mimeType, encoding; string reportName = "/Reports/DummyReport"; ReportService.Warning[] warnings; string[] ids; ReportExporter.Export( "ReportExecutionServiceSoap" new NetworkCredential("username", "password", "domain"), reportName, parameters.ToArray(), ExportFormat.HTML4, out output, out extension, out mimeType, out encoding, out warnings, out ids ); //------------------------------------------------------------- // Set HTTP Response Header to show download dialog popup //------------------------------------------------------------- Response.AddHeader("content-disposition", string.Format("attachment;filename=GeneratedExcelFile{0:yyyyMMdd}.{1}", DateTime.Today, extension)); return new FileContentResult(output, mimeType); }
因此,结果是您可以将parameter passing给SSRS报告服务器,该服务器将返回以HTMLforms呈现的报告。 一切都出现在一个页面上。 这是我能find的最好的解决scheme