web-dev-qa-db-fra.com

Comment utiliser un contrôle reportviewer dans une vue asp.net mvc 3 razor?

J'essaie d'utiliser un contrôle reportviewer, dans une vue rasoir, dans le cadre mvc 3. Le documentation en ligne parle de glisser-déposer. Toute suggestion sur la façon de l'insérer dans la vue.

60
Arun

La solution suivante ne fonctionne que pour les rapports d'une page. Reportez-vous aux commentaires pour plus de détails.

ReportViewer est un contrôle 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 ou un formulaire Web traditionnel contenant un ReportViewer dans l'application.

Vous devrez vous assurer que vous avez ajouté le gestionnaire pertinent dans votre web.config .

Si vous utilisez une page de vue ASPX ou un contrôle utilisateur de vue, vous devez définir AsyncRendering sur false pour que le rapport s'affiche correctement.

Mise à jour:

Ajout de plus de code exemple. Notez qu'il n'y a pas de changements significatifs requis dans Global.asax.

Web.Config

Le mien s'est terminé 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 le résultat de "TestReport.rdlc" sous la forme d'un 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

Le ASPXView est 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 à:

<%@ 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

http://blogs.msdn.com/b/sajoshi/archive/2010/06/16/asp-net-mvc-handling-ssrs-reports-with-reportviewer-part-i.aspx

lier le rapport à reportviewer dans le Web mvc2

78
Adrian Toman

C'est une tâche simple. Vous pouvez suivre les étapes suivantes.

  1. Créez un dossier dans votre solution et nommez-le Reports .
  2. Ajoutez un formulaire Web ASP.Net et nommez-le ReportView.aspx
  3. Créez une classe ReportData et ajoutez-la au dossier Reports . 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; }  
    }
    
  4. 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);
                    }
                }
            }
        }
    }
    
  5. Ajoutez ScriptManager à la page ReportView.aspx . Ajoutez maintenant une visionneuse de rapports à la page. Dans l'afficheur de rapport, définissez la propriété AsyncRendering = "false" . Le code est donné ci-dessous.

        <rsweb:ReportViewer ID="ReportViewerRSFReports" runat="server" AsyncRendering="false"
            Width="1271px" Height="1000px" >
        </rsweb:ReportViewer>
    
  6. Ajoutez deux NameSpace dans ReportView.aspx.cs

    using Microsoft.Reporting.WebForms;
    using System.IO;
    
  7. Modifiez le System.Web.UI.Page en ReportBasePage . Il suffit de remplacer votre code en utilisant ce qui suit.

    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();
        }
    }
    
  8. Ajouter un dossier au rapports Dossier et nommez-le Report . Ajoutez maintenant un rapport [~ # ~] rdlc [~ # ~] au ) Reports/Report dossier et nommez-le ClosingInventory.rdlc .

  9. Ajoutez maintenant 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();
        }
    
  10. Ajoutez une page de vue en cliquant sur le contrôleur ReportViewer . Nommez la page d'affichage 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" />
    
    }
    
  11. Ajoutez un Iframe . Définissez la propriété de l'Iframe comme suit

    frameborder="0"  width="1000"; height="1000"; style="overflow:hidden;"
    scrolling="no"
    
  12. Ajoutez le code 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&parameters=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;
    }
    
  13. Web.config fichier ajoute la clé suivante à la section appSettings

    add key="UnobtrusiveJavaScriptEnabled" value="true"
    
  14. Dans system.web gestionnaires Section ajoutez 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"
    
  15. Changez votre source de données pour la vôtre. Cette solution est très simple et je pense que tout le monde va en profiter.

12
Md. Nazrul Islam

Voici la solution complète pour intégrer directement un contrôle visualiseur de rapports (ainsi que tout contrôle côté serveur asp.net) dans une vue MVC .aspx, qui fonctionnera également sur un rapport comportant plusieurs pages (contrairement à la réponse d'Adrian Toman) et avec AsyncRendering défini sur true (basé sur "Framework ASP.NET MVC" de Steve Sanderson).

Ce qu'il faut faire, c'est fondamentalement:

  1. Ajouter un formulaire avec runat = "serveur"

  2. Ajoutez le contrôle (pour les contrôles de la visionneuse de rapports, cela peut aussi parfois fonctionner même avec AsyncRendering = "True" mais pas toujours, alors vérifiez dans votre cas spécifique)

  3. Ajouter des scripts côté serveur en utilisant des balises de script avec runat = "serveur"

  4. Remplacez l'événement Page_Init par le code indiqué ci-dessous pour permettre l'utilisation de PostBack et de 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!

Toutefois, cela n’est dit que pour les données, cela est nécessaire pour chaque publication, ou même si elles ne sont nécessaires que pour l’initialisation si elles ne sont pas gourmandes en données, et que les données ne doivent pas non plus dépendre des valeurs PostBack et ViewState.

Cependant, même une utilisation intensive de données peut parfois être encapsulée dans une expression lambda, puis transmise à la vue pour y être appelée.

Quelques notes cependant:

  • En faisant cela, la vue devient essentiellement un formulaire Web avec tous ses inconvénients (par exemple, les publications, et la possibilité que des contrôles non Asp.NET soient remplacés).
  • Le hack de override Page_Init est non documenté et peut être modifié à tout moment.
7
yoel halb

J'utilise ASP.NET MVC3 avec SSRS 2008 et je ne pouvais pas faire en sorte que @ Adrian fonctionne à 100% pour moi lorsque j'essayais d'obtenir des rapports à partir d'un serveur distant.

Enfin, j'ai trouvé que je devais changer la méthode Page_Load dans ViewUserControl1.ascx pour ressembler à ceci:

ReportViewer1.ProcessingMode = ProcessingMode.Remote;
ServerReport serverReport = ReportViewer1.ServerReport;
serverReport.ReportServerUrl = new Uri("http://<Server Name>/reportserver");
serverReport.ReportPath = "/My Folder/MyReport";
serverReport.Refresh();

Il me manquait le ProcessingMode.Remote .

Les références:

http://msdn.Microsoft.com/en-us/library/aa337091.aspx - ReportViewer

7
wilsjd

Il y a un assistant MvcReportViewer dans NuGet.

http://www.nuget.org/packages/MvcReportViewer/

Et voici les détails:

https://github.com/ilich/MvcReportViewer

J'ai utilisé cela. Cela fonctionne très bien.

6
Hayu Rahiza

Vous devrez non seulement utiliser une page asp.net, mais

Si vous utilisez Entity Framework ou LinqToSql (si vous utilisez des classes partielles), déplacez les données dans un projet séparé, le concepteur de rapport ne peut pas voir les classes.

Déplacez les rapports vers un autre projet/dll, VS10 contient des bogues, car les projets asp.net ne peuvent pas voir les sources de données des objets dans les applications Web. Ensuite, diffusez les rapports de la DLL dans la page ASPX de votre projet MVC.

Ceci s’applique aux projets mvc et webform. L'utilisation de rapports SQL en mode local n'est pas une expérience de développement agréable. Surveillez également la mémoire de votre serveur Web si vous exportez des rapports volumineux. Le rapport/exportateur est très mal conçu.

1
user965445

les documentations font référence à une application ASP.NET.
Vous pouvez essayer de regarder ma réponse ici .
J'ai un exemple joint à ma réponse.
Un autre exemple pour ASP.NET MVC3 peut être trouvé ici .

1
LeftyX

Il est possible d’obtenir un rapport SSRS sur une page MVC sans utiliser d’iFrames ou une page aspx.

Le gros du travail est expliqué ici:

http://geekswithblogs.net/stun/archive/2010/02/26/executing-reporting-services-web-service-from-asp-net-mvc-using-wcf-add-service-reference. aspx

Le lien explique comment créer un service Web et une méthode d'action MVC qui vous permettront d'appeler le service de génération de rapports et de rendre le résultat du service Web sous forme de fichier Excel. Avec une petite modification du code dans l'exemple, vous pouvez le rendre au format HTML.

Tout ce que vous avez à faire est alors d’utiliser un bouton pour appeler une fonction javascript qui effectue un appel AJAX à votre action MVC qui renvoie le code HTML du rapport. Lorsque AJAX appel retourne avec le code HTML remplace simplement un div avec ce code HTML.

Nous utilisons AngularJS donc mon exemple ci-dessous est dans ce format, mais il pourrait s'agir de n'importe quelle fonction 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);
    });

};

Et la méthode d'action - principalement tirée du lien ci-dessus ...

    [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);
    }

Le résultat est donc que vous devez passer des paramètres à un serveur de rapports SSRS qui renvoie un rapport que vous rendez au format HTML. Tout apparaît sur la même page. C'est la meilleure solution que j'ai pu trouver

1
Neil