私は、mvc 3フレームワークで、カミソリビュー内でreportviewerコントロールを使用しようとしています。 オンラインドキュメント ドラッグアンドドロップの話。ビューに挿入する方法に関する提案。
次のソリューションは、単一ページのレポートでのみ機能します。詳細についてはコメントを参照してください。
ReportViewerはサーバーコントロールであるため、カミソリビュー内では使用できません。ただし、ASPXビューページ、ビューユーザーコントロール、またはReportViewerを含む従来のWebフォームをアプリケーションに追加できます。
web.configに関連するハンドラー を追加したことを確認する必要があります。
ASPXビューページまたはビューユーザーコントロールを使用する場合、レポートを適切に表示するには、AsyncRenderingをfalseに設定する必要があります。
更新:
サンプルコードを追加しました。 Global.asaxに必要な意味のある変更はありません。
Web.Config
鉱山は次のようになりました:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.Microsoft.com/fwlink/?LinkId=152368
-->
<configuration>
<appSettings>
<add key="webpages:Version" value="1.0.0.0"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add Assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add Assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add Assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add Assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add Assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add Assembly="Microsoft.ReportViewer.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
</assemblies>
</compilation>
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>
<pages>
<namespaces>
<add namespace="System.Web.Helpers" />
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="System.Web.WebPages"/>
</namespaces>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
<handlers>
<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>
<runtime>
<assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
コントローラー
コントローラーのアクションは非常に簡単です。
ボーナスとして、File()アクションは「TestReport.rdlc」の出力をPDFファイルとして返します。
using System.Web.Mvc;
using Microsoft.Reporting.WebForms;
...
public class PDFController : Controller
{
public ActionResult Index()
{
return View();
}
public FileResult File()
{
ReportViewer rv = new Microsoft.Reporting.WebForms.ReportViewer();
rv.ProcessingMode = ProcessingMode.Local;
rv.LocalReport.ReportPath = Server.MapPath("~/Reports/TestReport.rdlc");
rv.LocalReport.Refresh();
byte[] streamBytes = null;
string mimeType = "";
string encoding = "";
string filenameExtension = "";
string[] streamids = null;
Warning[] warnings = null;
streamBytes = rv.LocalReport.Render("PDF", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
return File(streamBytes, mimeType, "TestReport.pdf");
}
public ActionResult ASPXView()
{
return View();
}
public ActionResult ASPXUserControl()
{
return View();
}
}
ASPXView.apsx
ASPXViewは次のとおりです。
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>ASPXView</title>
</head>
<body>
<div>
<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
ReportViewer1.LocalReport.ReportPath = Server.MapPath("~/Reports/TestReport.rdlc");
ReportViewer1.LocalReport.Refresh();
}
</script>
<form id="Form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<rsweb:reportviewer id="ReportViewer1" runat="server" height="500" width="500" AsyncRendering="false"></rsweb:reportviewer>
</form>
</div>
</body>
</html>
ViewUserControl1.ascx
ASPXユーザーコントロールは次のようになります。
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ 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_Load(object sender, System.EventArgs e)
{
ReportViewer1.LocalReport.ReportPath = Server.MapPath("~/Reports/TestReport.rdlc");
ReportViewer1.LocalReport.Refresh();
}
</script>
<form id="Form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<rsweb:ReportViewer ID="ReportViewer1" runat="server" AsyncRendering="false"></rsweb:ReportViewer>
</form>
ASPXUserControl.cshtml
かみそりの眺め。 ViewUserControl1.ascxが必要です。
@{
ViewBag.Title = "ASPXUserControl";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>ASPXUserControl</h2>
@Html.Partial("ViewUserControl1")
参考文献
これは簡単なタスクです。次の手順を実行できます。
クラスを作成しますReportDataそしてそれをReportsフォルダー。次のコードをクラスに追加します。
public class ReportData
{
public ReportData()
{
this.ReportParameters = new List<Parameter>();
this.DataParameters = new List<Parameter>();
}
public bool IsLocal { get; set; }
public string ReportName { get; set; }
public List<Parameter> ReportParameters { get; set; }
public List<Parameter> DataParameters { get; set; }
}
public class Parameter
{
public string ParameterName { get; set; }
public string Value { get; set; }
}
別のクラスを追加して名前を付けますReportBasePage.csこのクラスに次のコードを追加します。
public class ReportBasePage : System.Web.UI.Page
{
protected ReportData ReportDataObj { get; set; }
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (HttpContext.Current != null)
if (HttpContext.Current.Session["ReportData"] != null)
{
ReportDataObj = HttpContext.Current.Session["ReportData"] as ReportData;
return;
}
ReportDataObj = new ReportData();
CaptureRouteData(Page.Request);
}
private void CaptureRouteData(HttpRequest request)
{
var mode = (request.QueryString["rptmode"] + "").Trim();
ReportDataObj.IsLocal = mode == "local" ? true : false;
ReportDataObj.ReportName = request.QueryString["reportname"] + "";
string dquerystr = request.QueryString["parameters"] + "";
if (!String.IsNullOrEmpty(dquerystr.Trim()))
{
var param1 = dquerystr.Split(',');
foreach (string pm in param1)
{
var rp = new Parameter();
var kd = pm.Split('=');
if (kd[0].Substring(0, 2) == "rp")
{
rp.ParameterName = kd[0].Replace("rp", "");
if (kd.Length > 1) rp.Value = kd[1];
ReportDataObj.ReportParameters.Add(rp);
}
else if (kd[0].Substring(0, 2) == "dp")
{
rp.ParameterName = kd[0].Replace("dp", "");
if (kd.Length > 1) rp.Value = kd[1];
ReportDataObj.DataParameters.Add(rp);
}
}
}
}
}
ScriptManagerをReportView.aspxページ。次に、Report Viewerをページに追加します。レポートビューアーで、プロパティAsyncRendering = "false"を設定します。以下にコードを示します。
<rsweb:ReportViewer ID="ReportViewerRSFReports" runat="server" AsyncRendering="false"
Width="1271px" Height="1000px" >
</rsweb:ReportViewer>
2つの追加NameSpace in ReportView.aspx.cs
using Microsoft.Reporting.WebForms;
using System.IO;
System.Web.UI.PageをReportBasePage。次を使用してコードを置き換えるだけです。
public partial class ReportView : ReportBasePage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
RenderReportModels(this.ReportDataObj);
}
}
private void RenderReportModels(ReportData reportData)
{
// This is the Data Access Layer from which a method is called to fill data to the list.
RASolarERPData dal = new RASolarERPData();
List<ClosingInventoryValuation> objClosingInventory = new List<ClosingInventoryValuation>();
// Reset report properties.
ReportViewerRSFReports.Height = Unit.Parse("100%");
ReportViewerRSFReports.Width = Unit.Parse("100%");
ReportViewerRSFReports.CssClass = "table";
// Clear out any previous datasources.
this.ReportViewerRSFReports.LocalReport.DataSources.Clear();
// Set report mode for local processing.
ReportViewerRSFReports.ProcessingMode = ProcessingMode.Local;
// Validate report source.
var rptPath = Server.MapPath(@"./Report/" + reportData.ReportName +".rdlc");
//@"E:\RSFERP_SourceCode\RASolarERP\RASolarERP\Reports\Report\" + reportData.ReportName + ".rdlc";
//Server.MapPath(@"./Report/ClosingInventory.rdlc");
if (!File.Exists(rptPath))
return;
// Set report path.
this.ReportViewerRSFReports.LocalReport.ReportPath = rptPath;
// Set report parameters.
var rpPms = ReportViewerRSFReports.LocalReport.GetParameters();
foreach (var rpm in rpPms)
{
var p = reportData.ReportParameters.SingleOrDefault(o => o.ParameterName.ToLower() == rpm.Name.ToLower());
if (p != null)
{
ReportParameter rp = new ReportParameter(rpm.Name, p.Value);
ReportViewerRSFReports.LocalReport.SetParameters(rp);
}
}
//Set data paramater for report SP execution
objClosingInventory = dal.ClosingInventoryReport(this.ReportDataObj.DataParameters[0].Value);
// Load the dataSource.
var dsmems = ReportViewerRSFReports.LocalReport.GetDataSourceNames();
ReportViewerRSFReports.LocalReport.DataSources.Add(new ReportDataSource(dsmems[0], objClosingInventory));
// Refresh the ReportViewer.
ReportViewerRSFReports.LocalReport.Refresh();
}
}
Reportsフォルダーにフォルダーを追加し、名前を付けますReport。 [〜#〜] rdlc [〜#〜]レポートをReports/Reportフォルダと名前を付けますClosingInventory.rdlc。
コントローラーを追加して、名前を付けますReportControllerコントローラーで、次のアクションメソッドを追加します。
public ActionResult ReportViewer()
{
ViewData["reportUrl"] = "../Reports/View/local/ClosingInventory/";
return View();
}
ReportViewer Controllerをクリックして、ビューページを追加します。ビューページに名前を付けますReportViewer.cshtmlビューページに次のコードを追加します。
@using (Html.BeginForm("Login"))
{
@Html.DropDownList("ddlYearMonthFormat", new SelectList(ViewBag.YearMonthFormat, "YearMonthValue",
"YearMonthName"), new { @class = "DropDown" })
Stock In Transit: @Html.TextBox("txtStockInTransit", "", new { @class = "LogInTextBox" })
<input type="submit" onclick="return ReportValidationCheck();" name="ShowReport"
value="Show Report" />
}
Iframeを追加します。 Iframeのプロパティを次のように設定します
frameborder="0" width="1000"; height="1000"; style="overflow:hidden;"
scrolling="no"
ビューアに次のJavaScriptを追加します。
function ReportValidationCheck() {
var url = $('#hdUrl').val();
var yearmonth = $('#ddlYearMonthFormat').val();
var stockInTransit = $('#txtStockInTransit').val()
if (stockInTransit == "") {
stockInTransit = 0;
}
if (yearmonth == "0") {
alert("Please Select Month Correctly.");
}
else {
//url = url + "dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit;
url = "../Reports/ReportView.aspx?rptmode=local&reportname=ClosingInventory¶meters=dpSpYearMonth=" + yearmonth + ",rpYearMonth=" + yearmonth + ",rpStockInTransit=" + stockInTransit;
var myframe = document.getElementById("ifrmReportViewer");
if (myframe !== null) {
if (myframe.src) {
myframe.src = url;
}
else if (myframe.contentWindow !== null && myframe.contentWindow.location !== null) {
myframe.contentWindow.location = url;
}
else { myframe.setAttribute('src', url); }
}
}
return false;
}
Web.configファイルは次のキーをappSettingsセクション
add key="UnobtrusiveJavaScriptEnabled" value="true"
system.webhandlersセクションは次のキーを追加します
add verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
データソースを独自のものに変更します。このソリューションは非常にシンプルで、誰もが楽しめると思います。
以下は、レポートビューアーコントロール(およびasp.netサーバー側コントロール)をMVC .aspxビューに直接統合するための完全なソリューションです。このビューは、複数のページ(Adrian Tomanの回答とは異なります)およびAsyncRenderingをtrueに設定(Steve Sandersonによる「Pro ASP.NET MVC Framework」に基づく)。
基本的に次のことを行う必要があります。
Runat = "server"でフォームを追加します
コントロールを追加します(レポートビューアーコントロールの場合、AsyncRendering = "True"でも動作することもありますが、常にではないため、特定のケースを確認してください)
Runat = "server"のスクリプトタグを使用してサーバー側のスクリプトを追加する
以下に示すコードでPage_Initイベントをオーバーライドし、PostBackとViewstateの使用を有効にします
デモは次のとおりです。
<form ID="form1" runat="server">
<rsweb:ReportViewer ID="ReportViewer1" runat="server" />
</form>
<script runat="server">
protected void Page_Init(object sender, EventArgs e)
{
Context.Handler = Page;
}
//Other code needed for the report viewer here
</script>
もちろん、コントローラーで必要なすべてのデータを準備し、ViewModelを介してビューに渡すことにより、MVCアプローチを完全に活用することをお勧めします。
これにより、ビューを再利用できます!
ただし、これはすべてのポストバックに必要なデータについてのみ、またはデータ集約型ではない場合に初期化のみに必要であり、データもPostBackおよびViewStateの値に依存する必要はありません。
ただし、データを集中的に使用する場合でも、ラムダ式にカプセル化してから、ビューに渡してそこで呼び出すことができます。
ただし、いくつかのメモ:
SSRS 2008でASP.NET MVC3を使用していますが、リモートサーバーからレポートを取得しようとすると、@ Adrianを100%動作させることができませんでした。
最後に、ViewUserControl1.ascxのPage_Loadメソッドを次のように変更する必要があることがわかりました。
ReportViewer1.ProcessingMode = ProcessingMode.Remote;
ServerReport serverReport = ReportViewer1.ServerReport;
serverReport.ReportServerUrl = new Uri("http://<Server Name>/reportserver");
serverReport.ReportPath = "/My Folder/MyReport";
serverReport.Refresh();
ProcessingMode.Remoteがありませんでした。
参照:
http://msdn.Microsoft.com/en-us/library/aa337091.aspx -ReportViewer
NuGetにはMvcReportViewerヘルパーがあります。
http://www.nuget.org/packages/MvcReportViewer/
そしてこれが詳細です:
https://github.com/ilich/MvcReportViewer
これを使用しています。それは素晴らしい作品です。
Asp.netページを使用するだけでなく、
Entity FrameworkまたはLinqToSqlを使用して(部分クラスを使用している場合)データを別のプロジェクトに移動すると、レポートデザイナーはクラスを表示できません。
レポートを別のプロジェクト/ dllに移動すると、VS10にはバグがあり、asp.netプロジェクトではWebアプリのオブジェクトデータソースを表示できません。次に、dllからレポートをmvcプロジェクトのaspxページにストリーミングします。
これは、mvcおよびwebformプロジェクトに適用されます。ローカルモードでsqlレポートを使用するのは、楽しい開発経験ではありません。また、大きなレポートをエクスポートする場合は、Webサーバーのメモリを監視してください。 reportviewer/exportの設計は非常に不十分です。
IFrameまたはaspxページを使用せずに、SSRSレポートをMVCページに表示することができます。
作業の大部分は次のとおりです。
このリンクは、レポートサービスを呼び出してWebサービスの結果をExcelファイルとして表示できるWebサービスとMVCアクションメソッドの作成方法を説明しています。例のコードを少し変更するだけで、HTMLとしてレンダリングできます。
その後、ボタンを使用して、JavaScript関数を呼び出し、レポートのHTMLを返すMVCアクションをAJAX呼び出します。AJAX HTMLの呼び出しは、divをこのHTMLに置き換えるだけです。
私たちはAngularJSを使用しているので、以下の例はその形式になっていますが、任意のjavascript関数を使用できます
$scope.getReport = function()
{
$http({
method: "POST",
url: "Report/ExportReport",
data:
[
{ Name: 'DateFrom', Value: $scope.dateFrom },
{ Name: 'DateTo', Value: $scope.dateTo },
{ Name: 'LocationsCSV', Value: $scope.locationCSV }
]
})
.success(function (serverData)
{
$("#ReportDiv").html(serverData);
});
};
そして、アクションメソッド-主に上記のリンクから取得...
[System.Web.Mvc.HttpPost]
public FileContentResult ExportReport([FromBody]List<ReportParameterModel> parameters)
{
byte[] output;
string extension, mimeType, encoding;
string reportName = "/Reports/DummyReport";
ReportService.Warning[] warnings;
string[] ids;
ReportExporter.Export(
"ReportExecutionServiceSoap"
new NetworkCredential("username", "password", "domain"),
reportName,
parameters.ToArray(),
ExportFormat.HTML4,
out output,
out extension,
out mimeType,
out encoding,
out warnings,
out ids
);
//-------------------------------------------------------------
// Set HTTP Response Header to show download dialog popup
//-------------------------------------------------------------
Response.AddHeader("content-disposition", string.Format("attachment;filename=GeneratedExcelFile{0:yyyyMMdd}.{1}", DateTime.Today, extension));
return new FileContentResult(output, mimeType);
}
その結果、パラメーターをSSRSレポートサーバーに渡して、HTMLとしてレンダリングするレポートを返します。すべてが1ページに表示されます。これは私が見つけることができる最高のソリューションです