J'essaie d'utiliser un contrôle reportviewer, dans une vue razor, dans le cadre mvc 3. Le site documentation en ligne parle de glisser-déposer. Avez-vous une suggestion sur la façon de l'insérer dans la vue ?
Réponses
Trop de publicités?La solution suivante ne fonctionne que pour les rapports à page unique. Reportez-vous aux commentaires pour plus de détails.
ReportViewer est un contrôle de serveur et ne peut donc pas être utilisé dans une vue rasoir. Cependant, vous pouvez ajouter une page de vue ASPX, un contrôle utilisateur de vue ou un formulaire web traditionnel contenant un ReportViewer dans l'application.
Vous devez vous assurer que vous avez ajouté l'option dans votre web.config .
Si vous utilisez une page de visualisation ASPX ou un contrôle utilisateur de visualisation, vous devrez définir la valeur AsyncRendering à false pour que le rapport s'affiche correctement.
Mise à jour :
Ajouté plus d'exemples de code. Notez qu'il n'y a pas de changements significatifs requis dans Global.asax.
Web.Config
La mienne s'est terminée comme suit :
<?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>
Contrôleur
Les actions du contrôleur sont très simples.
En prime, l'action File() renvoie la sortie de "TestReport.rdlc" sous forme de fichier 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
L'ASPXView se présente comme suit.
<%@ 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
Le contrôle utilisateur ASPX ressemble à ceci :
<%@ 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
Vue rasoir. Nécessite ViewUserControl1.ascx.
@{
ViewBag.Title = "ASPXUserControl";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>ASPXUserControl</h2>
@Html.Partial("ViewUserControl1")
Références
C'est une tâche simple. Vous pouvez suivre les étapes suivantes.
-
Créez un dossier dans votre solution et nommez-le Rapports .
-
Ajouter un formulaire web ASP.Net et le nommer ReportView.aspx
-
Créer une classe ReportData et l'ajouter à la Rapports dossier. Ajoutez le code suivant à la classe.
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; } }
-
Ajoutez une autre classe et nommez-la ReportBasePage.cs . Ajoutez le code suivant dans cette classe.
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); } } } } }
-
Ajouter ScriptManager à la ReportView.aspx page. Ajoutez maintenant un Visionneuse de rapports à la page. Dans le visualisateur de rapports, définissez la propriété AsyncRendering="faux" . Le code est donné ci-dessous.
<rsweb:ReportViewer ID="ReportViewerRSFReports" runat="server" AsyncRendering="false" Width="1271px" Height="1000px" > </rsweb:ReportViewer>
-
Ajoutez deux Espace nom en ReportView.aspx.cs
using Microsoft.Reporting.WebForms; using System.IO;
-
Changez le System.Web.UI.Page à ReportBasePage . Il suffit de remplacer votre code par le suivant.
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(); } }
-
Ajouter un dossier au Rapports Dossier et nommez-le Rapport . Maintenant, ajoutez un RDLC rapport au Rapports/rapports et nommez-le ClosingInventory.rdlc .
-
Maintenant, ajoutez un contrôleur et nommez-le ReportController . Dans le contrôleur, ajoutez la méthode d'action suivante.
public ActionResult ReportViewer() { ViewData["reportUrl"] = "../Reports/View/local/ClosingInventory/"; return View(); }
-
Pour ajouter une page de vue, cliquez sur le bouton ReportViewer Contrôleur. Nommez la page de vue ReportViewer.cshtml . Ajoutez le code suivant à la page d'affichage.
@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" /> }
-
Ajouter un Iframe . Définissez la propriété de l'Iframe comme suit
frameborder="0" width="1000"; height="1000"; style="overflow:hidden;" scrolling="no"
-
Ajoutez le JavaScript suivant à la visionneuse.
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 ajoutez la clé suivante au fichier appSettings section
add key="UnobtrusiveJavaScriptEnabled" value="true"
-
Sur système.web manipulateurs La section ajoute la clé suivante
add verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
-
Changez votre source de données pour la vôtre. Cette solution est très simple et je pense que tout le monde l'appréciera.
J'utilise ASP.NET MVC3 avec SSRS 2008 et je n'ai pas réussi à faire fonctionner à 100% la solution de @Adrian lorsque j'ai essayé d'obtenir des rapports à partir d'un serveur distant.
Finalement, j'ai découvert que je devais modifier la méthode Page_Load dans le fichier ViewUserControl1.ascx pour ressembler à ça :
ReportViewer1.ProcessingMode = ProcessingMode.Remote;
ServerReport serverReport = ReportViewer1.ServerReport;
serverReport.ReportServerUrl = new Uri("http://<Server Name>/reportserver");
serverReport.ReportPath = "/My Folder/MyReport";
serverReport.Refresh();
J'avais manqué le ProcessingMode.Remote .
Références :
http://msdn.microsoft.com/en-us/library/aa337091.aspx - ReportViewer
Voici la solution complète pour intégrer directement un contrôle de visualisation de rapport (ainsi que n'importe quel contrôle asp.net côté serveur) dans une vue .aspx MVC, qui fonctionnera également sur un rapport comportant plusieurs pages (contrairement à la réponse d'Adrian Toman) et avec AsyncRendering réglé sur true, (basé sur "Pro ASP.NET MVC Framework" de Steve Sanderson).
Ce qu'il faut faire, c'est essentiellement :
-
Ajoutez un formulaire avec runat = "server".
-
Ajoutez le contrôle (pour les contrôles de type report-viewer, cela peut parfois fonctionner même avec AsyncRendering="True" mais pas toujours, vérifiez dans votre cas spécifique)
-
Ajouter des scripts côté serveur en utilisant les balises script avec runat = "server".
-
Remplacez l'événement Page_Init par le code ci-dessous, pour permettre l'utilisation de PostBack et Viewstate.
Voici une démonstration :
<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>
Il est bien sûr recommandé d'utiliser pleinement l'approche MVC, en préparant toutes les données nécessaires dans le contrôleur, puis en les transmettant à la vue via le ViewModel.
Cela permettra la réutilisation de la vue !
Cependant, cela ne s'applique qu'aux données qui sont nécessaires pour chaque postback, ou même si elles ne sont nécessaires que pour l'initialisation si elles ne sont pas intensives en données, et les données ne doivent pas non plus dépendre des valeurs PostBack et ViewState.
Cependant, même les données intensives peuvent parfois être encapsulées dans une expression lambda, puis transmises à la vue pour y être appelées.
Quelques remarques cependant :
- En faisant cela, la vue se transforme essentiellement en un formulaire web avec tous ses inconvénients (c'est-à-dire les retours en arrière et la possibilité de remplacer des contrôles non Asp.NET).
- Le piratage de Page_Init n'est pas documenté et peut être modifié à tout moment.
Il existe une aide MvcReportViewer dans NuGet.
http://www.nuget.org/packages/MvcReportViewer/
Et voici les détails :
https://github.com/ilich/MvcReportViewer
Je l'ai utilisé. Il fonctionne très bien.