我正在使用我的“ReportViewer”视图中使用@ Html.Partial调用的ascx控件在我的MVC应用程序中集成SSRS报告。
在ascx中,我有SSRS ReportViewer控件,在页面加载方法中,我使用传入模型的数据来设置ReportViewer的属性,如ReportPath等。
报表呈现正常,但列排序和分页等交互功能不起作用。该报告似乎令人耳目一新,但显示的数据保持不变。我在报表管理器中执行报表时排序和分页工作正常,但在我的应用程序中没有。
这是我的ascx:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<FEMTSWeb.Application.ViewModels.ReportViewerViewModel>" %>
<%@ 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_Init(object sender, System.EventArgs e)
{
Context.Handler = this.Page;
}
private void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ReportViewer1.ServerReport.ReportServerUrl = new Uri(ConfigurationManager.AppSettings["ReportServerUri"]);
ReportViewer1.ServerReport.DisplayName = Model.DisplayName;
ReportViewer1.ServerReport.ReportPath = Model.ReportPath;
ReportViewer1.AsyncRendering = false;
ReportViewer1.KeepSessionAlive = false;
ReportViewer1.ServerReport.Refresh();
}
}
</script>
<form runat="server" id="frmReportViewer">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div style="border-style:solid;">
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Visible="true" Width="100%" Height="100%"
AsyncRendering="false"
ProcessingMode="Remote"
SizeToReportContent="true"
InteractivityPostBackMode="AlwaysAsynchronous"
/>
</div>
</form>
以下是我称之为ascx的视图:
@model FEMTSWeb.Application.ViewModels.ReportViewerViewModel
@{
ViewBag.Title = "ReportViewer";
}
<h2>Report Viewer</h2>
@Html.Partial("_ReportViewer", model: (FEMTSWeb.Application.ViewModels.ReportViewerViewModel)ViewData["ReportViewerModel"])
答案 0 :(得分:0)
ReportViewer是一个需要viewstate的控件,MVC没有。 要做分页,你有两个选择, 1.将当前页面保留在会话中并使用ajax保留当前页面。 2.在页面上保留一个隐藏的iframe,使用jquery刷新它,然后用iframe的内容替换页面。这给出了伪异步的感觉。
关于#1的注释,ReportViewer在呈现报告之前(页面加载后)不确定总页数,因此最好的办法是在页面加载时抓住它并告诉会话它是什么,以便您可以更好地导航报告。
**
** ReportViewerControl.ascx - 包含ReportViewer Control的部分视图。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NMBS.Models.SelectedReport>" %>
<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<form id="Form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<rsweb:ReportViewer ID="ReportViewer" runat="server" Width="652px" AsyncRendering="false">
</rsweb:ReportViewer>
</form>
<script runat="server">
/* Prepare the ReportViewer Control to be Displayed */
private void Page_Load(object sender, System.EventArgs e)
{
// Set the PageCount Mode to Actual (Exact) instead of the Default (Approx.)
ReportViewer.PageCountMode = PageCountMode.Actual;
// Load Report Definition.
// Load DataSets.
// Etc...
ReportViewer.CurrentPage = Convert.ToInt32(Session["CurrentPage"]);
ReportViewer.LocalReport.Refresh();
}
</script>
ReportView.cshtml - 将显示ReportViewer Partial的Razor View。
@* ReportViewer Control *@
<div id="div-report">
@* Load the Report Viewer *@
@Html.Partial("ReportViewerControl", this.ViewData.Model) <br />
</div>
@* Scripts *@
<script type="text/javascript" src="/Scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="/Scripts/Json2.js"></script>
<script type="text/javascript" src="/Scripts/ReportView-Scripts.js"></script>
ReportView-Scripts - 用于加载ReportViewer并正确导航的脚本。
// Since the ReportViewer Control determines the PageCount at render time, we must
// send back the Total Page Count for us to use later.
function SetTotalPages() {
var CurrentPage = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(4) > input").val(),
PageCount = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(8) > span").html();
// Send JSON to /Report/SetPageCount/.
// /Report/SetPageCount/ this action sets the variable Session["PageCount"] equal to the variable passed to it.
$.ajax({
url:"/Report/SetPageCount/",
type: "POST",
dataType: "json",
data: "{ Count:" + PageCount + "}",
cache: false,
contentType: 'application/json; charset=utf-8',
success: function (response, textStatus, jqXHR)
{ },
error: function (jqXHR, textStatus, errorThrown)
{ }
});
// When done, update the Information.
$("#txtNavigation").val(CurrentPage.toString() + " of " + PageCount.toString());
// Don't do unnecessary Ajax Calls.
// If the Report is already on the First page, don't try navigating to Previous or First.
Nav.UpdateFunctionality();
}
var Nav = {
// If passed true, Enables First and Previous buttons.
// If passed false, Disables them.
ToggleFirstPrev: function ToggleFirstPrevNav(Toggle) {
var NavBar = $("#span-navigation");
if (Toggle == true) {
// Enable First and Previous.
NavBar.children("input[title=First]").removeAttr("disabled");
NavBar.children("input[title=Previous]").removeAttr("disabled");
} else {
// Disable First and Previous.
NavBar.children("input[title=First]").attr("disabled", true);
NavBar.children("input[title=Previous]").attr("disabled", true);
}
},
ToggleLastNext: function ToggleLastNextNav(Toggle) {
var NavBar = $("#span-navigation");
if (Toggle == true) {
// Enable First and Previous.
NavBar.children("input[title=Last]").removeAttr("disabled");
NavBar.children("input[title=Next]").removeAttr("disabled");
} else {
// Disable First and Previous.
NavBar.children("input[title=Last]").attr("disabled", true);
NavBar.children("input[title=Next]").attr("disabled", true);
}
},
UpdateFunctionality: function UpdateNavBarFunctionaility() {
var CurrentPage = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(4) > input").val(),
PageCount = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(8) > span").html(),
Navi = Nav;
// Don't do unnecessary Ajax Calls.
// If the Report is already on the First page, don't try navigating to Previous or First.
if (parseInt(CurrentPage, 10) <= 1) {
Navi.ToggleFirstPrev(false);
} else {
Navi.ToggleFirstPrev(true);
}
// If the Report is already on the Last page, don't try navigating to Next or Last.
if (parseInt(CurrentPage, 10) >= parseInt(PageCount, 10)) {
Navi.ToggleLastNext(false);
} else {
Navi.ToggleLastNext(true);
}
}
};
// Makes an Ajax call telling the Action (NavReportControl) which navigation button was clicked.
// It then on the Server-Side updates the CurrentPage Counter to the New Page (based on Nav Button Clicked).
// On Success it Refreshes the Iframe. On Iframe Load it copies over the new ReportViewer Control.
// (Reason we do it this way is because without the IFrame we'd have to do it synchronously to get the
// ReportViewer Control to do it's Initialize Function).
function NavReport(e) {
// Gets what Navigation Action the user is trying to accomplish. (Next, Previous, First, Last) (and also Apply but that'll Change)
var Navi = { Nav: $(this).val() },
CurrentPage = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(4) > input").val(),
PageCount = $("#Form1 > span > div > table > tbody > tr:eq(2) > td > div > div > div:eq(0) > table > tbody > tr > td:eq(8) > span").html();
// Get the New ReportViewer Control.
$.ajax({
type: "GET",
dataType: "json",
data: Navi,
cache: false,
contentType: 'application/json; charset=utf-8',
url: "/Report/NavReportControl",
success: function () {
RefreshiFrame();
}
});
}
**
**
// Refreshes the Iframe containing another instance of the ReportViewer Control.
function RefreshiFrame() {
// Hide the Report till update is finished.
$("#div-report").fadeOut(175);
// Refresh the Hidden Frame on the Page.
document.getElementById("iframe1").contentDocument.location.reload(true);
}
// This function is ran when the iFrame is finished loading.
// SrcName - Name of the Source iFrame. Ex. "#iframe1"
// DestName - Name of the Destination Div Ex. "#div-report"
function RefreshReport(SrcName, DestName) {
// Copy its "div-report" and CSS then replace it with the actual pages after reload.
var ReportViewer = $(SrcName).contents().find(DestName).html(),
CSS = $(SrcName).contents().find("head").children("[id*='ReportViewer']").clone(),
CurrentPage,
PageCount;
// Report Current ReportViewer with new ReportViewer.
$(DestName).html(ReportViewer);
//Add the New CSS to your current page.
$("head").append(CSS);
// Make sure the Report is visible.
$("#div-report").show();
// Update Nav Functionality.
// Don't do unnecessary Ajax Calls.
// If the Report is already on the First page, don't try navigating to Previous or First.
Nav.UpdateFunctionality();
}
答案 1 :(得分:0)
仅使用下面链接中的reportViewerExample文件夹,
https://github.com/ilich/MvcReportViewer
使用在线nuget软件包安装缺少的引用。在web.config中配置服务器路径,凭证(安装查看器后已在web.config中创建相关密钥),以及视图中的相应更改Index.chtml
它可以正常使用所有导航控件,无需重新加载页面。