有没有办法在ASP.net MVC视图上放置SQL Server Reporting Services报表查看器控件?如果不是......实现这一目标的最佳方法是什么?
答案 0 :(得分:16)
不,不是在MVC视图中。但是,您可以将一个Web表单页面与MVC站点混合在一起,其中包含服务器控件。
嗯,只是谷歌搜索“混合asp.net mvc和网络表格”找到一些例子,谷歌质疑我是否是人类:)
无论如何,这里有一个链接 - http://www.packtpub.com/article/mixing-asp.net-webforms-and-asp.net-mvc - 那里有几个。我也是出于同样的原因在MVC网站上完成了这个 - 报告控制。
答案 1 :(得分:14)
不,如果将它放在MVC视图中,则ReportViewer控件将不起作用,因为它需要ViewState。您必须创建一个旧式Web表单并将ReportViewer放在那里。
我在我工作的项目中使用的解决方案是创建自定义路由处理程序,因此我仍然可以使用URL路由。路由处理程序将从RouteData集合中获取类似报告名称的参数,创建我的Web表单的实例,并通过公共属性将参数传递给它。 Web表单将在Page_Load中读取这些内容并配置ReportViewer控件。
// Configure a route in Global.asax.cs that is handled by a ReportRouteHandler
routes.Add("ReportRoute", new Route("Reports/{reportName}",
new ReportRouteHandler());
public class ReportRouteHandler : IRouteHandler {
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
var reportName = requestContext.RouteData.Values["reportName"] as string;
var webform = BuildManager
.CreateInstanceFromVirtualPath("~/Path/To/ReportViewerWebForm.aspx",
typeof(Page)) as ReportViewerWebForm;
webform.ReportToShow = reportName;
return webform;
}
}
如果你决定使用这种方法,这个代码只是一个起点。我创建的那个也在返回之前做了一些用户身份验证和参数验证。
更新:看起来如果您使用的是ASP.NET 4.0,most of this can be done automatically!
答案 2 :(得分:11)
答案 3 :(得分:10)
在MVC中实现SSRS ReportViewer控件包含两个问题:
ReportViewer
如果您过去在设置ReportViewer控件方面做了很多工作,这可能是旧的,您可以跳到第2部分。
添加包/引用 - ReportViewer
控件存在于Microsoft.ReportViewer.WebForms.dll
中。您可以通过添加nuget:{/ p>中的Microsoft.ReportViewer.WebForms
包来包含在您的项目中
Web.config处理程序 - 根据Web.config Settings for ReportViewer上的这篇文章和this SO question,您需要将以下内容添加到web.config
}:
<system.web>
<httpHandlers>
<add verb="*" path="Reserved.ReportViewerWebControl.axd"
type="Microsoft.Reporting.WebForms.HttpHandler,
Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</httpHandlers>
</system.web>
<system.webServer>
<handlers>
<remove name="ReportViewerWebControlHandler" />
<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>
每this question on duplicate keys,它通常最容易删除,然后重新添加网络服务器配置
修复损坏的图片请求 - 报告查看器中存在blank.gif
images not loading已知缺陷,因此您可以将以下修复程序添加到global.asax.cs
:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpRequest req = HttpContext.Current.Request;
if (req.Url.PathAndQuery.StartsWith("/Reserved.ReportViewerWebControl.axd") &&
!req.Url.ToString().ToLower().Contains("iteration") &&
!String.IsNullOrEmpty(req.QueryString["ResourceStreamID"]) &&
req.QueryString["ResourceStreamID"].ToLower().Equals("blank.gif"))
{
Context.RewritePath(String.Concat(req.Url.PathAndQuery, "&IterationId=0"));
}
}
IgnoreRoute .axd - 如果还没有,请务必RouteConfig.cs
中的allow ScriptResources:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
添加ReportViewerPage.aspx - 添加一个包含ReportViewer控件实例的WebForm页面。为了工作,该控件需要找到ScriptManager
控件并放在<form runat="server" >
内。
所以你的新.aspx页面看起来应该是这样的:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ReportViewerPage.aspx.cs" Inherits="MVCAppWithReportViewer.ReportViewerPage" %>
<%@ Register TagPrefix="rsweb" Namespace="Microsoft.Reporting.WebForms" Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Report Viewer</title>
</head>
<body>
<form id="form1" runat="server">
<rsweb:ReportViewer ID="ReportViewer" runat="server"
Height="100%" Width="100%"
SizeToReportContent="True" ProcessingMode="Remote" />
<asp:ScriptManager ID="ScriptManager1" runat="server" />
</form>
</body>
</html>
在Page_Load
上连接ReportViewer - 假设您已将SSRS报告完全部署到报告服务器,该服务器位于以下地址:
http://ReportServerName/Reports/Pages/Report.aspx?ItemPath=%2fCompany%2fClientReport
然后,您的新WebForm页面中的代码隐藏应如下所示:
public partial class ReportViewerPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// confirm report properties (also setable in attributes)
ReportViewer.ProcessingMode = ProcessingMode.Remote;
// config variables
var reportServer = "ReportServerName";
var reportPath = "/Company/";
var reportName = "ClientReport";
// report setup
var serverReport = new ServerReport();
serverReport = ReportViewer.ServerReport;
serverReport.ReportServerUrl = new Uri($@"http://{reportServer}/ReportServer");
serverReport.ReportPath = $@"{reportPath}{reportName}";
// report input
var parameters = new List<ReportParameter>();
parameters.Add(new ReportParameter("User_uid", "1"));
serverReport.SetParameters(parameters);
// run report
serverReport.Refresh();
}
}
}
查看报告 - 此时,您应该可以通过选择在浏览器中查看或来查看自己的报告Ctrl + Shift + W
首先,让我们快速剖析如何加载和随后更新这些控件之间的路由差异
MVC 路由看起来像这个{controller}/{action}/{id}
,其中路由引擎会自动找到具有指定名称的Controller
和Action
以及传入请求将由该方法处理。在任何页面请求中,无论是来自页面加载,表单提交,按钮单击,锚点导航还是ajax调用,都会在URL {action}
中指定正在执行的确切方法。
WebForms 通过查找物理.aspx页面地址来路由到代码,然后使用ViewState&amp; PostData用于连接和触发该页面/控件上的事件。
这里是illustration of different routing formats in WebForms。这是一个简单的按钮点击事件,它会将帖子提交回父页面,并根据提交的事件数据在页面中引发相应的事件:
这对我们的解决方案来说是一个非常大的限制因素。 ReportViewer
控制没有什么特别之处。它只是一组复杂的UserControl类,它们通过回发当前地址以及ViewState和事件信息来响应点击和其他输入事件。因此,无论报告的路由和导航如何,都需要保留在我们的MVC包装器中。
选项1 - 为.aspx页面添加路线
从MVC 4.0+开始,您可以使用URL Routing with WebForms。通过添加MapPageRoute
(请注意页面部分)将路由映射到物理文件,这与MVC很好地融为一体。请将以下内容添加到RouteConfig.cs
:
routes.MapPageRoute(
routeName: "ReportViewer",
routeUrl: "ReportViewer/{reportName}",
physicalFile: "~/ReportViewerPage.aspx"
);
当您导航到地址~/Reports/reportName
时,报告将会运行。这可能是从控制器操作内部调用的,可能是某些用户输入的参数或web.config连接字符串。有很多ways to manage state in ASP.NET和Pass Values to ASP.NET Web Forms Pages。一种选择是在控制器中将会话和重定向中的信息存储起来:
HttpContext.Session[reportSetup.ReportName] = new ReportSetup() {ReportName = "ClientReport"}; //reportSetup;}
return RedirectToRoute("ReportViewer", new { reportName = reportSetup.ReportName});
然后,在.aspx页面内,您可以从RouteData值和会话中的任何设置参数中获取reportName
:
// get report name from route
string reportName = Page.RouteData.Values["reportName"].ToString();
// get model from session and clear
ReportSetup setup = (ReportSetup)HttpContext.Current.Session[reportName];
<强>赞成强>:
AyncRendering=True
<强>缺点强>:
选项2 - 在您网页上的.ascx
内嵌套PartialView
改编自How can I use a ReportViewer control with Razor?,您可以在PartialViews中使用.ascx
个控件,只要它们从System.Web.Mvc.ViewUserControl
继承。
创建一个名为ReportViewerControl.ascx
的新Web表单用户控件,如下所示:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ReportViewerControl.ascx.cs" Inherits="MVCAppWithReportViewer.ReportViewerControl" %>
<%@ Register TagPrefix="rsweb" Namespace="Microsoft.Reporting.WebForms" Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" %>
<form id="form1" runat="server">
<rsweb:ReportViewer ID="ReportViewer" runat="server"
Height="100%" Width="100%"
SizeToReportContent="True" ProcessingMode="Remote"
AsyncRendering="False" />
<asp:ScriptManager ID="ScriptManager1" runat="server"
EnablePartialRendering="false" />
</form>
注意:您必须设置
AsyncRendering="False"
和EnablePartialRendering="false"
在你背后的代码中,我需要将继承类型从System.Web.UI.UserControl
替换为System.Web.Mvc.ViewUserControl
。
在Page_Init
上,您需要将Context.Handler
设置为Page
,以便正确注册事件。
所以ReportViewerControl.ascx.cs
应该是这样的:
public partial class ReportViewerControl : System.Web.Mvc.ViewUserControl
{
protected void Page_Init(object sender, EventArgs e)
{
// Required for report events to be handled properly.
Context.Handler = Page;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
/* ... report setup ... */
serverReport.Refresh();
}
}
}
要呈现报告,请将以下内容添加到控制器视图中:
@Html.Partial("ReportViewerControl", Model)
然后在ReportViewerControl.ascx.cs Page_Load事件中,您可以从ViewUserControl.Model
属性中检索传入的模型,如下所示:
ReportSetup setup = (ReportSetup)Model;
优点:
_layout.cshtml
并在常规视图中使用<强>缺点强>:
AsyncRendering
必须设置为false,因此像分页和排序这样的交互会导致整页刷新,有时会让人感到不安。 Brian Hartman有一个专门针对ReportViewer的博客,并讨论了AsyncRendering and all the Baggage that Comes With It。进一步阅读:
答案 4 :(得分:4)
这有点简单,需要一些修复才能将一些不错的东西传递给MVC中的视图
public ActionResult Index()
{
/*Credentials of a user that has access to SSRS*/
string userid = "UserId";
string password = "MyPassword";
string domain = "MyDomain";
string reportURL="http://ServerName/ReportServer?/ReportsFolder/ReportName&Parameter=UserName&rs:Command=Render&rs:Format=PDF";
NetworkCredential nwc = new NetworkCredential(userid, password, domain);
WebClient client = new WebClient();
client.Credentials = nwc;
Byte[] pageData = client.DownloadData(reportURL);
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=" + DateTime.Now);
Response.BinaryWrite(pageData);
Response.Flush();
Response.End();
//return View();
}
答案 5 :(得分:3)
一个简单的解决方案是将一个iframe添加到您的MVC视图中,该视图可以从报表服务Web服务打开您想要的报表。 iframe将与报告服务中的组件完全一致。如果要将组件移动到MVC视图中,也可以动态控制iframe中用于url的参数(例如,使用ajax)。
虽然这有效,但您仍然需要登录网络报告服务(iframe将打开登录对话框)。对于IE,虽然使用您的Windows登录凭据,但这是“自动”完成的。
答案 6 :(得分:0)
通过使用Nuget进行安装,您可以使用ReportViewerForMvc在MVC中查看报告
Install-Package Microsoft.Report.Viewer -Version 11.0.0
Install-Package Microsoft.ReportViewer.Runtime.WebForms -Version 12.0.2402.15
Install-Package ReportViewerForMvc
如上所述安装了ReportViewer和其他必需的Nuget程序包后,在Visual Studio项目中添加一个新的Report.rdlc。
在上面创建的报告中添加数据集。rdlc
现在,在MVC中创建一个ActionMethod,它将从数据库中查询数据并返回报告
SSRSInMVC.Report.Report ds = new SSRSInMVC.Report.Report();
public ActionResult ReportStudent()
{
ReportViewer reportViewer = new ReportViewer();
reportViewer.ProcessingMode = ProcessingMode.Local;
reportViewer.SizeToReportContent = true;
reportViewer.Width = Unit.Percentage(900);
reportViewer.Height = Unit.Percentage(900);
var connectionString = ConfigurationManager.ConnectionStrings["SSRSInMVC.Properties.Settings.StudentsConnectionString"].ConnectionString;
SqlConnection conx = new SqlConnection(connectionString);
SqlDataAdapter adp = new SqlDataAdapter("SELECT * FROM Student_details", conx);
adp.Fill(ds, ds.Student_details.TableName);
reportViewer.LocalReport.ReportPath = Request.MapPath(Request.ApplicationPath) + @"Report\Report1.rdlc";
reportViewer.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", ds.Tables[0]));
ViewBag.ReportViewer = reportViewer;
return View();
}
在视图中,您具有以下代码
@using ReportViewerForMvc;
@{
ViewBag.Title = "Report Student";
}
<br/>
<br />
@Html.ReportViewer(ViewBag.ReportViewer as Microsoft.Reporting.WebForms.ReportViewer)
就这样,我们完成了。
答案 7 :(得分:0)
只要有帮助,这些视频教程就是我发现很容易理解的内容。
(您只需要容忍第一个视频中可怕的背景音乐即可。)
SSRS 2019 Report in ASP Net MVC 5
How To Filter SSRS 2019 Report Using Parameter
我必须安装“ ReportViewerForMvc14 ”而不是“ ReportViewerForMvc ”(该视频中已使用),因为它不再可用。包装上的注释说与原始包装相同,只是进行了更新以与ReportViewer 14.0一起使用。