如何在 ASP.Net MVC 中将 RDLC 报告与 ReportViewer 控件一起使用?
How can I use RDLC reports with the ReportViewer Control in ASP.Net MVC?
我对 ASP.Net MVC 还很陌生。我需要在 MVC 中显示基于 RDLC 的报告。
基本上我的要求以及我所做的是:-
我有一个继承 APIController 的 ReportController,它有一个 returns DataSet 的方法。此数据集被发送到 RDLC 文件。
为此,我做了以下操作,但无法使报告生效。
我创建了一个名为 ReportParameter 的模型 class,如下所示:
public class ReportParameter
{
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
}
我有以下控制器 ReportViewController :
public class ReportViewController : Controller
{
static readonly ReportController ctrl = new ReportController();
public ActionResult GenerateReport()
{
return View();
}
[HttpPost]
public ActionResult GenerateReport(ReportParameterSalesOrder param)
{
if (ModelState.IsValid)
{
Helpers.DataLayer dl = new Helpers.DataLayer();
if (param.DateFrom != null)
{
DateTime DateFrom = Convert.ToDateTime(param.DateFrom);
DateTime DateTo = Convert.ToDateTime(param.DateTo);
string fdate = DateFrom.ToString("yyyy/MM/dd");
string tdate = DateTo.ToString("yyyy/MM/dd");
Session["ReportSales"] = ctrl.ReportSales(param);
}
return Redirect(Url.Action("ViewReport", "ReportView"));
}
return View();
}
public ActionResult ViewReport()
{
return View();
}
}
我有一个 API 控制器 ReportController,其对象已在上面的 ReportViewerController 中创建,以生成数据集并填充 RDLC 报告。 API 控制器是:
public class ReportController : ApiController
{
static readonly IReportRepository repository = new ReportRepository();
[ActionName("ReportSales")]
public DataSet ReportSales(ReportParameterSalesOrder paramSO)
{
DataSet item = repository.ReportSales(paramSO);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
}
我有两个观点 GenerateReport.aspx 和 ViewReport.aspx。 GenerateReport.aspx 如下:
<table style="width: 40%;">
<tr>
<td class="style1">
<h3>
<asp:Label ID="Label1" runat="server" Text="From Date"></asp:Label></h3>
</td>
<td>
<%=@Html.EditorFor(a=> a.DateFrom, new{id="startDate",style="width:250px;"}) %>
<%=@Html.ValidationMessageFor(a => a.DateFrom)%>
</td>
</tr>
<tr>
<td class="style1">
<h3>
<asp:Label ID="Label2" runat="server" Text="To Date"></asp:Label></h3>
</td>
<td>
<%=@Html.EditorFor(a => a.DateTo, new { id = "ToDate", style = "width: 250px;" })%>
<%=@Html.ValidationMessageFor(a => a.DateTo)%>
</td>
</tr>
<tr>
<td class="style1">
</td>
<td>
</td>
</tr>
<tr>
<td class="style1">
</td>
<td>
<input id="btnsearch" class="button" type="submit" value="Show" />
</td>
</tr>
</table>
ViewReport.aspx如下:
<center style="width: 974px">
<iframe id="myReport" width="100%" height="450px" src="ReportViewer.aspx">
</iframe></center>
我添加了一个Dataset.xsd,一个rdlc文件和一个aspx页面来添加rdlc文件。
但我无法让它工作。如何显示报告,或者如何将从 Controller 接收到的数据集填充到报告中?
背景
(我知道你知道这一点,但对于未来的读者 ;-)
- Microsoft ReportViewer 控件需要 ViewState 和 WebForms ScriptManagers 才能正常工作,因此不适合在 MVC 视图中直接使用。
- 但是可以 运行 MVC 项目中的 WebForms 页面 - 因为它们 运行 在同一个 AppDomain 中,
Session
状态在 MVC 和 WebForms 之间共享。
详细
用于在 MVC 视图的 iframe
中呈现 ReportViewer 控件的 ViewReport.aspx
页面需要是一个很好的老式 asp.Net 网络表单。
对于小型数据集,您可以在 MVC 控制器中获取报告数据,然后在 Session
中将其传递给 WebForm。
但是,对于较大的数据集,我建议您改为将参数传递给会话中的 WebForm(或者甚至通过 QueryString
,如果它们不敏感的话),然后是 WebForm隐藏代码需要获取数据集并将其绑定到 ReportViewer。
在 MVC 端,在 MyController
参数中 post:
[HttpPost]
public ActionResult GenerateReport(string param1, int param2)
{
// Obviously you apply the parameters as predicates and hit the real database
Session["ReportData"] = FakeDatabaseData;
ViewBag.ShowIFrame = true;
return View();
}
一旦用户在视图中输入 ReportParameters,您就可以显示 IFrame,MyController/GenerateReport
:
<iframe src='<%= Url.Content("~/OldSkoolAspx/ReportViewer.aspx") %>' width="100%" height="450px"></iframe>
然后将 WebForms 页面添加到您的 MVC 项目中 /OldSkoolAspx/ReportViewer.aspx
。在 ReportViewer.aspx.cs
后面的代码中:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var reportDataSource = new ReportDataSource
{
// Must match the DataSource in the RDLC
Name = "SomeReportDataSet",
Value = Session["ReportData"]
};
ReportViewer1.LocalReport.DataSources.Add(reportDataSource);
ReportViewer1.DataBind();
}
}
并在 WebForms ReportViewer.aspx
前端添加控件(推荐使用工具箱,以便将所有必需的引用添加到 web.config):
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana" Font-Size="8pt" WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt" Width="476px">
<LocalReport ReportPath="MyReport.rdlc">
</LocalReport>
</rsweb:ReportViewer>
<asp:ScriptManager runat="server" ID="SillyPrerequisite"></asp:ScriptManager>
这里有很多变动的部分,所以我上传了一个演示项目到 GitHub over here
请注意,相同的技术也适用于报表服务器生成的报表(即使用 ReportViewer 和 .RDL 报表)。但是请注意 RDLC 和 RDL 都可能是真实的 SessionState
hogs
我对 ASP.Net MVC 还很陌生。我需要在 MVC 中显示基于 RDLC 的报告。
基本上我的要求以及我所做的是:-
我有一个继承 APIController 的 ReportController,它有一个 returns DataSet 的方法。此数据集被发送到 RDLC 文件。
为此,我做了以下操作,但无法使报告生效。
我创建了一个名为 ReportParameter 的模型 class,如下所示:
public class ReportParameter
{
public DateTime DateFrom { get; set; }
public DateTime DateTo { get; set; }
}
我有以下控制器 ReportViewController :
public class ReportViewController : Controller
{
static readonly ReportController ctrl = new ReportController();
public ActionResult GenerateReport()
{
return View();
}
[HttpPost]
public ActionResult GenerateReport(ReportParameterSalesOrder param)
{
if (ModelState.IsValid)
{
Helpers.DataLayer dl = new Helpers.DataLayer();
if (param.DateFrom != null)
{
DateTime DateFrom = Convert.ToDateTime(param.DateFrom);
DateTime DateTo = Convert.ToDateTime(param.DateTo);
string fdate = DateFrom.ToString("yyyy/MM/dd");
string tdate = DateTo.ToString("yyyy/MM/dd");
Session["ReportSales"] = ctrl.ReportSales(param);
}
return Redirect(Url.Action("ViewReport", "ReportView"));
}
return View();
}
public ActionResult ViewReport()
{
return View();
}
}
我有一个 API 控制器 ReportController,其对象已在上面的 ReportViewerController 中创建,以生成数据集并填充 RDLC 报告。 API 控制器是:
public class ReportController : ApiController
{
static readonly IReportRepository repository = new ReportRepository();
[ActionName("ReportSales")]
public DataSet ReportSales(ReportParameterSalesOrder paramSO)
{
DataSet item = repository.ReportSales(paramSO);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
}
我有两个观点 GenerateReport.aspx 和 ViewReport.aspx。 GenerateReport.aspx 如下:
<table style="width: 40%;">
<tr>
<td class="style1">
<h3>
<asp:Label ID="Label1" runat="server" Text="From Date"></asp:Label></h3>
</td>
<td>
<%=@Html.EditorFor(a=> a.DateFrom, new{id="startDate",style="width:250px;"}) %>
<%=@Html.ValidationMessageFor(a => a.DateFrom)%>
</td>
</tr>
<tr>
<td class="style1">
<h3>
<asp:Label ID="Label2" runat="server" Text="To Date"></asp:Label></h3>
</td>
<td>
<%=@Html.EditorFor(a => a.DateTo, new { id = "ToDate", style = "width: 250px;" })%>
<%=@Html.ValidationMessageFor(a => a.DateTo)%>
</td>
</tr>
<tr>
<td class="style1">
</td>
<td>
</td>
</tr>
<tr>
<td class="style1">
</td>
<td>
<input id="btnsearch" class="button" type="submit" value="Show" />
</td>
</tr>
</table>
ViewReport.aspx如下:
<center style="width: 974px">
<iframe id="myReport" width="100%" height="450px" src="ReportViewer.aspx">
</iframe></center>
我添加了一个Dataset.xsd,一个rdlc文件和一个aspx页面来添加rdlc文件。
但我无法让它工作。如何显示报告,或者如何将从 Controller 接收到的数据集填充到报告中?
背景
(我知道你知道这一点,但对于未来的读者 ;-)
- Microsoft ReportViewer 控件需要 ViewState 和 WebForms ScriptManagers 才能正常工作,因此不适合在 MVC 视图中直接使用。
- 但是可以 运行 MVC 项目中的 WebForms 页面 - 因为它们 运行 在同一个 AppDomain 中,
Session
状态在 MVC 和 WebForms 之间共享。
详细
用于在 MVC 视图的 iframe
中呈现 ReportViewer 控件的 ViewReport.aspx
页面需要是一个很好的老式 asp.Net 网络表单。
对于小型数据集,您可以在 MVC 控制器中获取报告数据,然后在 Session
中将其传递给 WebForm。
但是,对于较大的数据集,我建议您改为将参数传递给会话中的 WebForm(或者甚至通过 QueryString
,如果它们不敏感的话),然后是 WebForm隐藏代码需要获取数据集并将其绑定到 ReportViewer。
在 MVC 端,在 MyController
参数中 post:
[HttpPost]
public ActionResult GenerateReport(string param1, int param2)
{
// Obviously you apply the parameters as predicates and hit the real database
Session["ReportData"] = FakeDatabaseData;
ViewBag.ShowIFrame = true;
return View();
}
一旦用户在视图中输入 ReportParameters,您就可以显示 IFrame,MyController/GenerateReport
:
<iframe src='<%= Url.Content("~/OldSkoolAspx/ReportViewer.aspx") %>' width="100%" height="450px"></iframe>
然后将 WebForms 页面添加到您的 MVC 项目中 /OldSkoolAspx/ReportViewer.aspx
。在 ReportViewer.aspx.cs
后面的代码中:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var reportDataSource = new ReportDataSource
{
// Must match the DataSource in the RDLC
Name = "SomeReportDataSet",
Value = Session["ReportData"]
};
ReportViewer1.LocalReport.DataSources.Add(reportDataSource);
ReportViewer1.DataBind();
}
}
并在 WebForms ReportViewer.aspx
前端添加控件(推荐使用工具箱,以便将所有必需的引用添加到 web.config):
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana" Font-Size="8pt" WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt" Width="476px">
<LocalReport ReportPath="MyReport.rdlc">
</LocalReport>
</rsweb:ReportViewer>
<asp:ScriptManager runat="server" ID="SillyPrerequisite"></asp:ScriptManager>
这里有很多变动的部分,所以我上传了一个演示项目到 GitHub over here
请注意,相同的技术也适用于报表服务器生成的报表(即使用 ReportViewer 和 .RDL 报表)。但是请注意 RDLC 和 RDL 都可能是真实的 SessionState
hogs