Dis*_*ile 51 c# asp.net-mvc reportviewer reporting-services
有没有办法在ASP.net MVC视图上放置SQL Server Reporting Services报表查看器控件?如果不是......实现这一目标的最佳方法是什么?
Mik*_*ner 16
不,不是在MVC视图中.但是,您可以拥有一个Web表单页面,其中包含与MVC站点混合的服务器控件.
嗯,只是谷歌搜索"混合asp.net mvc和网络表单"找到一些例子,谷歌质疑我是否是人类:)
无论如何,这里有一个链接 - http://www.packtpub.com/article/mixing-asp.net-webforms-and-asp.net-mvc - 那里有一些.我也是出于同样的原因在MVC网站上完成了这个 - 报告控制.
Bra*_*bby 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;
}
}
Run Code Online (Sandbox Code Playgroud)
当然,如果你决定使用这种方法,这个代码只是一个起点.我创建的那个也在返回之前做了一些用户身份验证和参数验证.
更新:看起来如果你使用的是ASP.NET 4.0,大部分都可以自动完成!
Kyl*_*Mit 10
在MVC中实现SSRS ReportViewer控件包含两个问题:
ReportViewer
如果你在过去设置过ReportViewer控件已经做了很多工作,这可能是旧的,你可以跳到第2部分.
添加包/引用 - ReportViewer
控件存在于Microsoft.ReportViewer.WebForms.dll
.您可以通过添加Microsoft.ReportViewer.WebForms
nuget中的包来包含在您的项目中:
Web.config处理程序 - 根据Web.config上的这篇文章ReportViewer的设置,这个SO问题,您需要将以下内容添加到您的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>
Run Code Online (Sandbox Code Playgroud)
根据重复键的这个问题,通常最容易删除然后重新添加webserver配置
修复损坏的图像请求 - ReportViewer中存在已知的缺陷,blank.gif
图像未加载,因此您可以将以下修复添加到您的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"));
}
}
Run Code Online (Sandbox Code Playgroud)IgnoreRoute个.axd -如果不是已经存在,一定要允许ScriptResources在RouteConfig.cs
:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Run Code Online (Sandbox Code Playgroud)添加ReportViewerPage.aspx - 添加一个WebForm页面,该页面将包含ReportViewer控件的实例.为了工作,该控件需要找到一个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>
Run Code Online (Sandbox Code Playgroud)连接ReportViewerPage_Load
- 假设您已经将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();
}
}
}
Run Code Online (Sandbox Code Playgroud)查看报告 - 此时,您应该可以通过选择在浏览器中查看或Ctrl+ Shift+ 来查看自己的报告W
首先,让我们快速剖析如何加载和随后更新这些控件之间的路由差异
MVC路由看起来像这样{controller}/{action}/{id}
,路由引擎将自动找到Controller
并Action
具有指定名称,并且传入请求将由该方法处理.在任何页面请求中,无论是来自页面加载,表单提交,按钮单击,锚点导航还是ajax调用,都会在URL中指定正在执行的确切方法{action}
.
WebForms通过查找物理.aspx页面地址路由到代码,然后使用ViewState和PostData连接并触发该页面/控件上的事件.
以下是WebForms中不同路由格式的说明.这是一个简单的按钮点击事件,它会将帖子提交回父页面,并根据提交的事件数据在页面中引发相应的事件:
这对我们的解决方案来说是一个非常大的限制.ReportViewer
控制没有什么特别之处.它只是一组复杂的UserControl类,它们通过回发当前地址以及ViewState和事件信息来响应点击和其他输入事件.因此,无论报告的路由和导航如何,都需要持久保存到我们的MVC包装器中.
选项1 - 为.aspx页面添加路由
从MVC 4.0+开始,您可以将URL Routing与WebForms一起使用.通过添加(注意Page部分)将路由映射到物理文件,这与MVC混合得很好.所以将以下内容添加到您的:MapPageRoute
RouteConfig.cs
routes.MapPageRoute(
routeName: "ReportViewer",
routeUrl: "ReportViewer/{reportName}",
physicalFile: "~/ReportViewerPage.aspx"
);
Run Code Online (Sandbox Code Playgroud)
导航到该地址时将运行该报告~/Reports/reportName
.这可能是从控制器操作内部调用的,可能是某些用户输入的参数或web.config连接字符串.有很多方法可以在ASP.NET中管理状态并将值传递给ASP.NET Web窗体页.一种选择是在控制器中存储会话和重定向中的信息:
HttpContext.Session[reportSetup.ReportName] = new ReportSetup() {ReportName = "ClientReport"}; //reportSetup;}
return RedirectToRoute("ReportViewer", new { reportName = reportSetup.ReportName});
Run Code Online (Sandbox Code Playgroud)
然后,在.aspx页面内,您可以reportName
从RouteData值和会话中的任何设置参数中获取:
// 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];
Run Code Online (Sandbox Code Playgroud)
优点:
AyncRendering=True
缺点:
选项2 - 嵌入页面.ascx
内部PartialView
改编自如何使用Razor的ReportViewer控件?,.ascx
只要它们继承,就可以在PartialViews中使用控件System.Web.Mvc.ViewUserControl
.
创建一个名为的新Web窗体用户控件ReportViewerControl.ascx
,如下所示:
<%@ 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>
Run Code Online (Sandbox Code Playgroud)
注意:您必须设置
AsyncRendering="False"
和EnablePartialRendering="false"
在后面的代码中,您需要将继承类型替换System.Web.UI.UserControl
为System.Web.Mvc.ViewUserControl
.
然后Page_Init
,您需要设置Context.Handler
to,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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
要呈现报告,请将以下内容添加到控制器视图中:
@Html.Partial("ReportViewerControl", Model)
Run Code Online (Sandbox Code Playgroud)
然后在ReportViewerControl.ascx.cs Page_Load事件中,您可以从ViewUserControl.Model
属性中检索传入的模型,如下所示:
ReportSetup setup = (ReportSetup)Model;
Run Code Online (Sandbox Code Playgroud)
优点:
_layout.cshtml
并在常规视图中使用缺点:
AsyncRendering
必须设置为false,因此像分页和排序这样的交互会导致完整的页面刷新,有时候会变得很糟糕.布莱恩·哈特曼(Brian Hartman)有一个专门针对ReportViewer的博客,并讨论了AsyncRendering和所有随附的行李.进一步阅读:
归档时间: |
|
查看次数: |
67913 次 |
最近记录: |