如何在 ASP.NET MVC 中呈现 Active Reports WebViewer
我今天早些时候在 DataDynamics 论坛上问了这个问题。 我想也许我会在SO这里得到某种回应。
我正在尝试在我的 ASP.NET MVC 应用程序中启动并运行 WebViewer。 我试图在控制器中渲染 webviewer (webViewer.RenderControl(htmlTextWriter) ,然后将结果放入 ViewData 并在我的视图中显示报告。我什至不知道这是否是正确的方法。任何帮助 未将
控制器代码:
public ActionResult Display()
{
CurrentReport = new DetailedReport { ReportData = new DetailedData() { Repository = _repository } };
var webViewer = new WebViewer();
CurrentReport.Run();
webViewer.ID = "WebViewer1";
webViewer.Visible = true;
webViewer.ViewerType = ViewerType.HtmlViewer;
webViewer.Width = Unit.Percentage(100);
webViewer.Report = CurrentReport;
var stringWriter = new StringWriter();
var htmlTextWriter = new HtmlTextWriter(stringWriter);
webViewer.RenderBeginTag(htmlTextWriter);
webViewer.RenderControl(htmlTextWriter);
webViewer.RenderEndTag(htmlTextWriter);
ViewData["WebViewer"] = stringWriter.ToString();
return View();
}
Display.aspx 代码:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Admin.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register assembly="ActiveReports.Web, Version=5.2.1013.2, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" namespace="DataDynamics.ActiveReports.Web" tagprefix="ActiveReportsWeb" %>
<%@ Import Namespace="xxxx.Core"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ClientAdminContent" runat="server">
<%=ViewData["WebViewer"] %>
</asp:Content>
错误:
对象引用设置为对象的实例。 描述:执行当前 Web 请求期间发生未处理的异常。 请查看堆栈跟踪以获取有关错误及其在代码中的来源的更多信息。
异常详细信息:System.NullReferenceException:未将对象引用设置为对象的实例。
源错误:
第 60 行:var htmlTextWriter = new HtmlTextWriter(stringWriter); 第 61 行:webViewer.RenderBeginTag(htmlTextWriter); 第 62 行:webViewer.RenderControl(htmlTextWriter); 第 63 行:webViewer.RenderEndTag(htmlTextWriter); 第 64 行:
源文件:C:\Projects\xxxx\xxxx\app\xxxx.Web.Controllers\ReportsController.cs 行:62
****更新:****
基于 scott 的回答(谢谢)我的控制器现在看起来像这样:
public ActionResult Display()
{
ViewData["Report"] = new DetailedReport { ReportData = new DetailedReport { ReportData = new DetailedData() { Repository = _repository } };
return View();
}
我的视图看起来像这样:(我的视图文件后面没有代码)。
<%
var report = (ActiveReport3) ViewData["Report"];
report.Run();
WebViewer1.Report = report;
%>
<ActiveReportsWeb:WebViewer ID="WebViewer1" runat="server" Height="100%" Width="100%" ViewerType="AcrobatReader" />
我看着它通过调试器,它似乎正确地单步执行“详细信息”部分,将值放入我的字段中。 但完成所有操作后,我收到消息“未指定报告。”我希望我真的不必在我的视图中使用代码隐藏文件,因为我没有在任何地方使用它们别的。 我还进行了调试以验证 report.Document.Pages.Count > 0. 我已将代码块放在 WebViewer 控件的上方和下方(不认为这真的很重要)。 还有其他想法吗?
****更新 #2:****
我最终使用了此处找到的答案:在 ASP.Net 中使用 OnLoad 事件的替代方法MVC View? 结合下面斯科特的优秀答案。 生成报告并将其绑定到控件是一个计时问题。 所以我的视图最终看起来像这样......(其中Model.Report是一个ActiveReport3)
<script runat="server">
private void Page_Load(object sender, EventArgs e)
{
var report = Model.Report;
report.Run();
WebViewer1.Report = report;
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="ClientAdminContent" runat="server">
<ActiveReportsWeb:WebViewer ID="WebViewer1" runat="server" Height="100%" Width="100%" ViewerType="AcrobatReader" />
</asp:Content>
感谢大家的帮助!
I asked this question in the DataDynamics forum earlier today. I thought that maybe I'd get some sort of response here at SO.
I am trying to get the WebViewer up and running in my ASP.NET MVC application.
I am attempting to render the webviewer in the controller (webViewer.RenderControl(htmlTextWriter) and then put the results into ViewData and display the report in my view. I dont' even know if this is the correct way to go about this. Any help would be greatly appreciated.
Controller code:
public ActionResult Display()
{
CurrentReport = new DetailedReport { ReportData = new DetailedData() { Repository = _repository } };
var webViewer = new WebViewer();
CurrentReport.Run();
webViewer.ID = "WebViewer1";
webViewer.Visible = true;
webViewer.ViewerType = ViewerType.HtmlViewer;
webViewer.Width = Unit.Percentage(100);
webViewer.Report = CurrentReport;
var stringWriter = new StringWriter();
var htmlTextWriter = new HtmlTextWriter(stringWriter);
webViewer.RenderBeginTag(htmlTextWriter);
webViewer.RenderControl(htmlTextWriter);
webViewer.RenderEndTag(htmlTextWriter);
ViewData["WebViewer"] = stringWriter.ToString();
return View();
}
Display.aspx code:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Admin.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register assembly="ActiveReports.Web, Version=5.2.1013.2, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" namespace="DataDynamics.ActiveReports.Web" tagprefix="ActiveReportsWeb" %>
<%@ Import Namespace="xxxx.Core"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ClientAdminContent" runat="server">
<%=ViewData["WebViewer"] %>
</asp:Content>
Error:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Source Error:
Line 60: var htmlTextWriter = new HtmlTextWriter(stringWriter);
Line 61: webViewer.RenderBeginTag(htmlTextWriter);
Line 62: webViewer.RenderControl(htmlTextWriter);
Line 63: webViewer.RenderEndTag(htmlTextWriter);
Line 64:
Source File: C:\Projects\xxxx\xxxx\app\xxxx.Web.Controllers\ReportsController.cs Line: 62
****Update:****
Based on the answer by scott (thank you) my controller now looks like this:
public ActionResult Display()
{
ViewData["Report"] = new DetailedReport { ReportData = new DetailedReport { ReportData = new DetailedData() { Repository = _repository } };
return View();
}
And my view looks like this: (I have no code behind files for my views).
<%
var report = (ActiveReport3) ViewData["Report"];
report.Run();
WebViewer1.Report = report;
%>
<ActiveReportsWeb:WebViewer ID="WebViewer1" runat="server" Height="100%" Width="100%" ViewerType="AcrobatReader" />
I watch it go through debugger, and it seems to correctly step through the Details section, putting values into my fields. But after all is done, I get the message "No Report Specified." I'm hoping that I really don't have to use a codebehind file on my view because I'm not using them anywhere else. I have also debugged to verify that report.Document.Pages.Count > 0. I have put the code block both above and below the WebViewer control (don't think that really matters). Any additional thoughts?
****Update #2:****
I ended up using the answer found here: Alternative to using the OnLoad event in an ASP.Net MVC View? in combination with scott's excellent answer below. It was a timing thing with generating and binding the report to the control. So my View looks like this in the end... (where Model.Report is an ActiveReport3)
<script runat="server">
private void Page_Load(object sender, EventArgs e)
{
var report = Model.Report;
report.Run();
WebViewer1.Report = report;
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="ClientAdminContent" runat="server">
<ActiveReportsWeb:WebViewer ID="WebViewer1" runat="server" Height="100%" Width="100%" ViewerType="AcrobatReader" />
</asp:Content>
Thanks for everyone's help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我们对此进行了内部调查并找到了以下解决方案。 您可以正常将 WebViewer 添加到视图中。 您的示例中不需要复杂的低级交互代码。 相反,只需将 WebViewer 通常添加到您的 aspx 视图中即可。 在我们的示例中,WebViewer 添加如下:
这足以让 WebViewer 在视图上工作。
在控制器中,我们指定了一个 ActiveReport,如下所示:
在视图的代码隐藏中,我们将报表挂接到视图:
然后棘手的部分开始了。 当在 ASP.NET 下运行某些查看器类型(例如 AcrobatReader / PDF)时,ActiveReports 使用一些 IHttpHandler。 为了确保我们的处理程序正常工作,您必须获取 ASP.NET MVC 路由以允许它们正常处理。 幸运的是,这样做很容易。 只需将以下代码行添加到 Global.asax.cs 文件中:
这将忽略该路由。 请注意,根据我的阅读,可能存在问题,因为 ASP.NET 路由似乎只允许像这样的单个“捕获所有”路由。 因此,如果您有多个 IgnoreRoute 命令,或者 .axd 文件有任何问题,则需要修改约束字典参数以适应 .axd 和 .ArCacheItem。
有关详细信息,请参阅以下文章: http://haacked.com/archive/2008/07/14/make-routing-ignore-requests-for-a-file-extension.aspx
您可以从我们的论坛下载完整的示例: http://www.datadynamics.com/forums/ShowPost.aspx?PostID =121907#121907
斯科特·维勒克
数据动态 / GrapeCity
We have investigated this internally and found the following solution. You can add the WebViewer to a View normally. There is no need for the complicated low-level interaction code in your example. Instead, just add the WebViewer to your aspx view normally. In our sample the WebViewer was added as follows:
That is enough to get the WebViewer working on the view.
In the controller we specified an ActiveReport as follows:
In the codebehind of the View we hook the report to the view:
Then the tricky part begins. There are some IHttpHandlers used by ActiveReports when running under ASP.NET for some of the viewer types such as AcrobatReader / PDF. To ensure our handlers are working you must get ASP.NET MVC routing to allow them to process as normal. Luckily it is easy to do so. Just add the following line of code to the Global.asax.cs file:
That will ignore the route. Note that according to my reading there may be problems since ASP.NET routing seems to allow only a single "catch all" route like this. Therefore, if you have multiple of these IgnoreRoute commands and or you have any problems with a .axd file, you'll need to modify the constraints dictionary argument to accomidate the .axd as well as .ArCacheItem.
For more information see the following article: http://haacked.com/archive/2008/07/14/make-routing-ignore-requests-for-a-file-extension.aspx
You can download the full sample from our forums at http://www.datadynamics.com/forums/ShowPost.aspx?PostID=121907#121907
Scott Willeke
Data Dynamics / GrapeCity
对于遇到此问题并使用 IIS7 的其他人,请确保在
部分而不是
下添加活动报告处理程序。我认为我的 IgnoreRoute 设置不正确,因为我收到了 404 错误。 不过,我正在遵循 ActiveReports 提供的教程,该教程将它们放在 IIS6 部分而不是 IIS7 部分。
For anyone else having this issue and using IIS7 Make sure you add the Active reports handlers under the
<handlers>
section not<httpHandlers>
.I thought i had the IgnoreRoute setup improperly because I was getting 404 errors. However I was following the tutorial given by ActiveReports which has them in the IIS6 section instead of IIS7.