【问题标题】:CrystalReportViewer Buttons Broken using MVC FrameworkCrystalReportViewer 按钮使用 MVC 框架损坏
【发布时间】:2009-12-18 01:10:41
【问题描述】:

我们正在使用 MVC 框架(第 5 版)和 CrystalReportViewer 控件来显示我们的报表。我无法让报表查看器控件顶部的任何按钮起作用。

如果我正在处理“HoursSummary”报告。如果我将鼠标悬停在 IE 中报表查看器上的任何按钮上,页面底部显示的链接是“../HoursSummary”。这将创建一个 'http://localhost/HoursSummary' 的 url。没有“HoursSummary”控制器,所以我不断收到 404 错误。

  • 我想我想重定向到“http://localhost/reports/HoursSummary”,因为我确实有一个报告控制器。如果这是正确的方法,有人知道我应该在 CrystalReportViewer 控件上设置哪个属性来实现吗?
  • 有没有更简单的方法来处理这种情况?

【问题讨论】:

  • 您能预见到为什么这可能不适用于使用 MS reportviewer 控件吗?
  • 我尝试了 MS 报告查看器,但由于某种原因,它一直无法正常工作。然而,我也有水晶报表在这一点上工作,从未完全追求它。
  • 为 VS2010 和 Crystal Reports 2010 更新:stackoverflow.com/questions/3902195/…

标签: asp.net-mvc crystal-reports


【解决方案1】:

如果那是一个服务器控件,它将不起作用。 ASP.NET MVC 不使用任何回发,因此大多数 webforms 服务器控件不起作用。

您可以将报表查看器嵌入到 iFrame 中并将其输出到您的 MVC 视图中。 iframe 可以指向 MVC 内容外部的页面,例如在名为 Legacy 的子文件夹中。

【讨论】:

    【解决方案2】:

    我们能够让报表查看器正常工作,并且过去几个月一直在生产中使用它,没有任何问题。

    • 我们有一个报告控制器,其中列出了指向我们要运行的报告的链接
    • 单击其中一个链接将对后端进行 ajax 调用并返回部分页面,我们可以在其中填写所需的所有参数。
    • 参数填写完毕后,我们将表单提交到“\reports\Name of Report”。
    • 回到 Reports 控制器,我们调用 SQL,返回我们的数据,然后调用另一个名为“完整报告”的视图
    • “完整报表”视图只有一个水晶报表查看器控件,它会自动获取我们通过 ViewData 传递给它的报表数据、填充报表、呈现报表并将其发送给用户

    一切似乎都很好。

    更新

    我在上面最初列出的步骤中添加了一些代码和说明。我遗漏的关键项目是最终视图背后有一些代码,因此它可以与 Crystal Reports 一起使用。后面的代码很少,但需要。为了使 Crystal Reports 正常工作,您最终会得到以下文件:

    • 设计报告的布局文件.rpt
    • 包含 Crystal Reports Report 控件的 aspx 文件。这是包含一些代码的文件。

    有关如何创建可与 Crystal Reports 一起使用的视图的详细信息:

    • 使用 Crystal Reports 设计器创建报表布局。生成的文件将是一个 .rpt 文件。为了这个例子,我们称这个文件为 AllJobsSummaryReportLayout.rpt。
    • 在设计报表时,为“数据库字段”选择一个业务实体或 DTO,该业务实体或 DTO 保存从 SQL 返回的结果。
    • 顺便说一句,我们的系统中有一些数据传输对象 (DTO),它们仅包含标量值和字符串,这些 DTO 中没有智能。当控制器被调用时,它会调用模型,大多数这些报告的模型返回一个 DTO 列表,然后我们将其传递给要呈现的视图。这些 DTO 不知道如何查询自己、显示自己,它们只包含从 SQL 返回的实际值,然后由其他人呈现。
    • 一旦布局水晶报表文件AllJobsSummaryReportLayout.rpt,我们设计我们的Controller。在控制器中,我们获取运行报告所需的任何参数,调用模型,模型返回我们的 DTO 列表,如下面的控制器中的 sn-p 所示:

      var reportViewData = model.AllJobsSummaryQuery(startDate, endDate);
      if (0 != reportViewData.Count())
      {
          var report = new AllJobsSummaryReportLayout();
          report.SetDataSource(reportViewData);
          report.SetParameterValue("startDate", startDate);
          report.SetParameterValue("endDate", endDate);
          ViewData["ReportData"] = report;
          returnView = "AllJobsSummaryView";
      }
      else
          returnView = "noReportView";
      return View(returnView);
      
    • 请注意这里的几项,我们正在创建一个变量“报告”,它是我们在上面创建的 Crystal Report 布局文件 AllJobsSummaryReportLayout.rpt 的一种类型。

    • 创建“报告”变量后,我们设置数据源值和所需的任何参数,并将项目捆绑到 ViewData 中。

    • 现在让我们来看看 AllJobsSummaryView.aspx。该文件上有一个带有 Crystal Reports 查看器的表单和一个代码隐藏文件:

    <%@ Page Title="All Jobs Summary Report" Language="C#" AutoEventWireup="true" CodeBehind="AllJobsSummaryView.aspx.cs" Inherits="V.Views.Reports.AllJobsSummaryView"%>     
    <%@ Register Assembly="CrystalDecisions.Web, Version=10.5.3700.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" Namespace="CrystalDecisions.Web" TagPrefix="CR" %> 
    <form id="form1" runat="server">
    <div>
    <a href="/Reports" id="Report"><< Return to Report Main
        Page</a><br />
    <CR:CrystalReportViewer ID="ReportViewer" runat="server" AutoDataBind="True" EnableDatabaseLogonPrompt="False"
        EnableParameterPrompt="False" HasCrystalLogo="False" DisplayGroupTree="False" 
        HasDrillUpButton="False" HasToggleGroupTreeButton="False" HasViewList="False" 
        HasSearchButton="False" EnableDrillDown="False" EnableViewState="True" 
        Height="50px" ReportSourceID="CrystalReportSource1" Width="350px" />    
    <CR:CrystalReportSource ID="CrystalReportSource1" runat="server">
        <Report FileName="AllJobsSummaryReportLayout.rpt">
        </Report>
    </CR:CrystalReportSource>
    </div>
    </form>
    
    • 以及文件背后的代码:

       using System;
       using System.Collections.Generic;
       using System.Linq;
       using System.Web;
       using System.Web.Mvc;
      
       namespace V.Views.Reports
       {
          public partial class AllJobsSummaryView : ViewPage
          {
              protected void Page_Init(object sender, EventArgs e)
              {
                  ReportViewer.ReportSource = ViewData["ReportData"];
              }
      
              protected void Page_Unload(object sender, EventArgs e)
              {
                  ((AllJobsSummaryReportLayout)ViewData["ReportData"]).Close();
                  ((AllJobsSummaryReportLayout)ViewData["ReportData"]).Dispose();
              }
          }
       }
      
    • Page_Unload 是关键,如果没有它,Crystal Reports 将生成错误“您已超出管理员设置的最大报告数。”

    这种方法在生产环境中已经运行了两年多。

    【讨论】:

    • 我正在尝试这样做。在最后一步中,您说您有一个带有 CrystalReportViewer 的视图。如果没有代码隐藏,我似乎无法让它正常工作。您能否提供更多详细信息并查看您的视图代码?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 2021-08-21
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多