ReportViewerForMVC

git-tfs-id: [http://192.168.1.10:8080/tfs/AyA]$/SINORT;C337
This commit is contained in:
dmendez 2018-07-27 21:44:10 +00:00
parent 04857860ce
commit aee48afa18
15 changed files with 783 additions and 0 deletions

View file

@ -0,0 +1,47 @@
using System;
using System.Reflection;
namespace ReportViewerForMvc
{
internal static class CopyPropertiesHelper
{
internal static void Copy<T>(ref T obj, T properties)
{
if (properties == null)
{
throw new ArgumentNullException("properties", "Value cannot be null.");
}
Copy<T, T>(ref obj, properties);
}
internal static void Copy<T1, T2>(ref T1 obj, T2 properties)
{
Type objType = obj.GetType();
Type propertiesType = properties.GetType();
BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;
foreach (PropertyInfo propertyInfo in propertiesType.GetProperties(bindingFlags))
{
try
{
if (propertyInfo.CanRead)
{
var valueToCopy = propertyInfo.GetValue(properties);
var objProperty = objType.GetProperty(propertyInfo.Name);
if (objProperty.CanWrite)
{
objProperty.SetValue(obj, valueToCopy);
}
}
}
catch (NullReferenceException ex)
{
throw ex;
}
catch (TargetInvocationException) { } //Do nothing, just like my boss.
}
}
}
}

View file

@ -0,0 +1,97 @@
using Microsoft.Reporting.WebForms;
using System.Web;
using System.Web.Mvc;
namespace ReportViewerForMvc
{
/// <summary>
/// HTML helpers for ReportViewerForMvc
/// </summary>
public static class HtmlHelperExtensions
{
/// <summary>
/// Returns an HTML iframe that renders an ASP.NET ReportViewer control.
/// </summary>
/// <param name="helper">The HTML helper instance that this method extends.</param>
/// <param name="reportViewer">The object containing the ReportViewer control properties.</param>
/// <returns>An HTML iframe that sets its heigh and width based on the content of the report.</returns>
public static HtmlString ReportViewer(this HtmlHelper helper, ReportViewer reportViewer)
{
return ReportViewerForMvc.GetIframe(reportViewer, null);
}
/// <summary>
/// Returns an HTML iframe that renders an ASP.NET ReportViewer control.
/// </summary>
/// <param name="helper">The HTML helper instance that this method extends.</param>
/// <param name="reportViewer">The object containing the ReportViewer control properties.</param>
/// <param name="htmlAttributes">The object containing the HTML attributes of the iframe.</param>
/// <returns>An HTML iframe with the specified attributes that sets its heigh and width based on the content of the report.</returns>
public static HtmlString ReportViewer(this HtmlHelper helper, ReportViewer reportViewer, object htmlAttributes)
{
return ReportViewerForMvc.GetIframe(reportViewer, htmlAttributes);
}
/// <summary>
/// Returns an HTML iframe that renders an ASP.NET ReportViewer control.
/// </summary>
/// <param name="helper">The HTML helper instance that this method extends.</param>
/// <param name="reportViewer">The object containing the ReportViewer control properties.</param>
/// <param name="report">An object containing the LocalReport/ServerReport properties.</param>
/// <returns>An HTML iframe that sets its heigh and width based on the content of the report.</returns>
public static HtmlString ReportViewer(this HtmlHelper helper, object reportViewer, object report)
{
ReportViewer reportViewerControl = ReportViewerForMvc.AnonymousReportViewer(reportViewer, report);
return ReportViewerForMvc.GetIframe(reportViewerControl, null);
}
/// <summary>
/// Returns an HTML iframe that renders an ASP.NET ReportViewer control.
/// </summary>
/// <param name="helper">The HTML helper instance that this method extends.</param>
/// <param name="reportViewer">The object containing the ReportViewer control properties.</param>
/// <param name="report">An object containing the LocalReport/ServerReport properties.</param>
/// <param name="htmlAttributes">The object containing the HTML attributes of the iframe.</param>
/// <returns>An HTML iframe with the specified attributes that sets its heigh and width based on the content of the report.</returns>
public static HtmlString ReportViewer(this HtmlHelper helper, object reportViewer, object report, object htmlAttributes)
{
ReportViewer reportViewerControl = ReportViewerForMvc.AnonymousReportViewer(reportViewer, report);
return ReportViewerForMvc.GetIframe(reportViewerControl, htmlAttributes);
}
/// <summary>
/// Returns an HTML iframe that renders an ASP.NET ReportViewer control.
/// </summary>
/// <param name="helper">The HTML helper instance that this method extends.</param>
/// <param name="reportViewer">The object containing the ReportViewer control properties.</param>
/// <param name="report">An object containing the LocalReport/ServerReport properties.</param>
/// <param name="parameters">Object that contains the parameters for a report.</param>
/// <param name="htmlAttributes">The object containing the HTML attributes of the iframe.</param>
/// <returns>An HTML iframe with the specified attributes that sets its heigh and width based on the content of the report.</returns>
public static HtmlString ReportViewer(this HtmlHelper helper, object reportViewer, object report, object parameters, object htmlAttributes)
{
ReportViewer reportViewerControl = ReportViewerForMvc.AnonymousReportViewer(reportViewer, report, parameters);
return ReportViewerForMvc.GetIframe(reportViewerControl, htmlAttributes);
}
/// <summary>
/// Returns an HTML iframe that renders an ASP.NET ReportViewer control.
/// </summary>
/// <param name="helper">The HTML helper instance that this method extends.</param>
/// <param name="reportViewer">The object containing the ReportViewer control properties.</param>
/// <param name="report">An object containing the LocalReport/ServerReport properties.</param>
/// <param name="parameters">Object that contains the parameters for a report.</param>
/// <param name="dataSources">The data sources to be added to the report.</param>
/// <param name="htmlAttributes">The object containing the HTML attributes of the iframe.</param>
/// <returns>An HTML iframe with the specified attributes that sets its heigh and width based on the content of the report.</returns>
public static HtmlString ReportViewer(this HtmlHelper helper, object reportViewer, object report, object parameters, object dataSources, object htmlAttributes)
{
ReportViewer reportViewerControl = ReportViewerForMvc.AnonymousReportViewer(reportViewer, report, parameters, dataSources);
return ReportViewerForMvc.GetIframe(reportViewerControl, htmlAttributes);
}
}
}

View file

@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
namespace ReportViewerForMvc
{
internal class IframeBuilder
{
internal static HtmlString Iframe(object htmlAttributes)
{
IDictionary<string, object> parsedHtmlAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
ReportViewerForMvc.IframeId = GetId(parsedHtmlAttributes);
string parsedIframe = CreateIframeTag(parsedHtmlAttributes);
parsedIframe += ReceiveMessageScript();
parsedIframe += SetIframeIdScript();
return new HtmlString(parsedIframe);
}
private static string GetId(IDictionary<string, object> htmlAttributes)
{
string id;
if (htmlAttributes["id"] == null)
{
id = "r" + Guid.NewGuid().ToString();
}
else
{
id = TagBuilder.CreateSanitizedId(htmlAttributes["id"].ToString());
if (id == null)
{
throw new ArgumentNullException("htmlAttributes.id", "Value cannot be null.");
}
}
return id;
}
private static string CreateIframeTag(IDictionary<string, object> htmlAttributes)
{
string applicationPath = (HttpContext.Current.Request.ApplicationPath == "/") ? "" : HttpContext.Current.Request.ApplicationPath;
TagBuilder tagBuilder = new TagBuilder("iframe");
tagBuilder.GenerateId(ReportViewerForMvc.IframeId);
tagBuilder.MergeAttribute("src", applicationPath +"/ReportViewerWebForm.aspx");
tagBuilder.MergeAttributes(htmlAttributes, false);
tagBuilder.SetInnerText("iframes not supported.");
return tagBuilder.ToString();
}
private static string ReceiveMessageScript()
{
string script = "<script src=\"" + WebResourceHelper.GetWebResourceUrl(typeof(ReportViewerForMvc), "ReportViewerForMvc.Scripts.ReceiveMessage.js") + "\"></script>";
return script;
}
private static string SetIframeIdScript()
{
string script = "<script>ReportViewerForMvc.setIframeId('" + ReportViewerForMvc.IframeId + "');</script>";
return script;
}
}
}

View file

@ -0,0 +1,34 @@
using Microsoft.Reporting.WebForms;
using System;
using System.Collections.Generic;
namespace ReportViewerForMvc
{
/// <summary>
/// ReportDataSourceCollectionExtensions helpers for ReportViewerForMvc
/// </summary>
public static class ReportDataSourceCollectionExtensions
{
/// <summary>
/// Adds the elements of the specified collection to the end of the ReportDataSourceCollection.
/// </summary>
/// <param name="reportDataSourceCollection">The ReportDataSourceCollection that this method extends.</param>
/// <param name="collection">The collection whose elements should be added to the end of the ReportDataSourceCollection.</param>
public static void Add(this ReportDataSourceCollection reportDataSourceCollection, IEnumerable<ReportDataSource> collection)
{
if (reportDataSourceCollection == null)
{
throw new ArgumentNullException("reportDataSourceCollection", "Value cannot be null.");
}
if (collection == null)
{
throw new ArgumentNullException("collection", "Value cannot be null.");
}
foreach (ReportDataSource reportDataSource in collection)
{
reportDataSourceCollection.Add(reportDataSource);
}
}
}
}

View file

@ -0,0 +1,59 @@
using Microsoft.Reporting.WebForms;
using System;
using System.Linq;
namespace ReportViewerForMvc
{
/// <summary>
/// ReportExtensions helpers for ReportViewerForMvc
/// </summary>
public static class ReportExtensions
{
/// <summary>
/// Set the ReportParameters of the specified ReportParameterInfoCollection.
/// </summary>
/// <param name="report">The Report that this method extends.</param>
/// <param name="collection">The collection whose ReportParameters should be added to the Report.</param>
public static void SetParameters(this Report report, ReportParameterInfoCollection collection)
{
if (report == null)
{
throw new ArgumentNullException("report", "Value cannot be null.");
}
if (collection == null)
{
throw new ArgumentNullException("collection", "Value cannot be null.");
}
foreach (ReportParameterInfo reportParameterInfo in collection)
{
report.SetParameters(reportParameterInfo);
}
}
/// <summary>
/// Set the ReportParameter of the specified ReportParameterInfo.
/// </summary>
/// <param name="report">The Report that this method extends.</param>
/// <param name="reportParameterInfo">The ReportParameterInfor whose parameter should be added to the Report.</param>
public static void SetParameters(this Report report, ReportParameterInfo reportParameterInfo)
{
if (report == null)
{
throw new ArgumentNullException("report", "Value cannot be null.");
}
if (reportParameterInfo == null)
{
throw new ArgumentNullException("reportParameterInfo", "Value cannot be null.");
}
ReportParameter reportParameter = new ReportParameter(
reportParameterInfo.Name,
reportParameterInfo.Values.ToArray(),
reportParameterInfo.Visible);
report.SetParameters(reportParameter);
}
}
}

View file

@ -0,0 +1,74 @@
using Microsoft.Reporting.WebForms;
using System;
using System.Linq;
namespace ReportViewerForMvc
{
/// <summary>
/// ReportViewerExtensions helpers for ReportViewerForMvc
/// </summary>
public static class ReportViewerExtensions
{
/// <summary>
/// Copy the properties of the specified ReportViewer to the ReportViewer.
/// </summary>
/// <param name="reportViewer">The ReportViewer that this method extends.</param>
/// <param name="properties">The ReportViewer whose properties should be copied to the ReportViewer.</param>
public static void SetProperties(this ReportViewer reportViewer, ReportViewer properties)
{
if (reportViewer == null)
{
throw new ArgumentNullException("reportViewer", "Value cannot be null.");
}
CopyPropertiesHelper.Copy<ReportViewer>(ref reportViewer, properties);
reportViewer.LocalReport.SetProperties(properties.LocalReport);
reportViewer.ServerReport.SetProperties(properties.ServerReport);
}
/// <summary>
/// Copy the properties of the specified LocalReport to the LocalReport.
/// </summary>
/// <param name="localReport">The LocalReport that this method extends.</param>
/// <param name="properties">The LocalReport whose properties should be copied to the LocalReport.</param>
public static void SetProperties(this LocalReport localReport, LocalReport properties)
{
if (localReport == null)
{
throw new ArgumentNullException("localReport", "Value cannot be null.");
}
CopyPropertiesHelper.Copy<LocalReport>(ref localReport, properties);
localReport.DataSources.Add(properties.DataSources.ToList());
try
{
localReport.SetParameters(properties.GetParameters());
}
catch (MissingReportSourceException) { } //Do nothing
}
/// <summary>
/// Copy the properties of the specified ServerReport to the ServerReport.
/// </summary>
/// <param name="serverReport">The ServerReport that this method extends.</param>
/// <param name="properties">The ServerReport whose properties should be copied to the ServerReport.</param>
public static void SetProperties(this ServerReport serverReport, ServerReport properties)
{
if (serverReport == null)
{
throw new ArgumentNullException("serverReport", "Value cannot be null.");
}
CopyPropertiesHelper.Copy<ServerReport>(ref serverReport, properties);
try
{
serverReport.SetParameters(properties.GetParameters());
}
catch (MissingReportSourceException) { } //Do nothing
}
}
}

View file

@ -0,0 +1,107 @@
using Microsoft.Reporting.WebForms;
using System;
using System.Web;
namespace ReportViewerForMvc
{
/// <summary>
/// Encapsulates the methods and properties used for the ReportViewerForMvc extension.
/// </summary>
public static class ReportViewerForMvc
{
internal static string IframeId { get; set; }
private static ReportViewer reportViewer;
internal static ReportViewer ReportViewer
{
get { return reportViewer; }
set
{
//TODO: Implement dynamic ID
reportViewer = value;
reportViewer.ID = "ReportViewer1";
}
}
internal static HtmlString GetIframe(ReportViewer reportViewer, object htmlAttributes)
{
if (reportViewer == null)
{
throw new ArgumentNullException("reportViewer", "Value cannot be null.");
}
ReportViewerForMvc.ReportViewer = reportViewer;
return IframeBuilder.Iframe(htmlAttributes);
}
/// <summary>
/// Constructs a ReporViewer
/// </summary>
/// <param name="reportViewer">The object containing the ReportViewer properties.</param>
/// <param name="report">An object containing the LocalReport/ServerReport properties.</param>
/// <returns>An instance of ReportViewer with the specified properties</returns>
public static ReportViewer AnonymousReportViewer(object reportViewer, object report)
{
return AnonymousReportViewer(reportViewer, report, null, null);
}
/// <summary>
/// Constructs a ReporViewer with parameters
/// </summary>
/// <param name="reportViewer">The object containing the ReportViewer properties.</param>
/// <param name="report">An object containing the LocalReport/ServerReport properties.</param>
/// <param name="parameters">Object that contains the parameters for a report.</param>
/// <returns>An instance of ReportViewer with the specified properties</returns>
public static ReportViewer AnonymousReportViewer(object reportViewer, object report, object parameters)
{
return AnonymousReportViewer(reportViewer, report, parameters, null);
}
/// <summary>
/// Constructs a ReporViewer with parameters and data sources.
/// </summary>
/// <param name="reportViewer">The object containing the ReportViewer properties.</param>
/// <param name="report">An object containing the LocalReport/ServerReport properties.</param>
/// <param name="parameters">Object that contains the parameters for a report.</param>
/// <param name="dataSources">The data sources to be added to the report.</param>
/// <returns>An instance of ReportViewer with the specified properties</returns>
public static ReportViewer AnonymousReportViewer(object reportViewer, object report, object parameters, object dataSources)
{
if (reportViewer == null)
{
throw new ArgumentNullException("reportViewer", "Value cannot be null.");
}
if (report == null)
{
throw new ArgumentNullException("report", "Value cannot be null.");
}
ReportViewer reportViewerControl = ReportViewerHelper.AnonymousToReportViewer(reportViewer);
if (reportViewerControl.ProcessingMode == ProcessingMode.Local)
{
reportViewerControl.LocalReport.SetProperties(ReportViewerHelper.AnonymousToLocalReport(report));
if (parameters != null)
{
reportViewerControl.LocalReport.SetParameters(ReportViewerHelper.AnonymousToReportParameter(parameters));
}
if (dataSources != null)
{
reportViewerControl.LocalReport.DataSources.Add(ReportViewerHelper.AnonymousToReportDataSourceList(dataSources));
}
}
else if (reportViewerControl.ProcessingMode == ProcessingMode.Remote)
{
reportViewerControl.ServerReport.SetProperties(ReportViewerHelper.AnonymousToServerReport(report));
if (parameters != null)
{
reportViewerControl.ServerReport.SetParameters(ReportViewerHelper.AnonymousToReportParameter(parameters));
}
}
return reportViewerControl;
}
}
}

View file

@ -0,0 +1,121 @@
using Microsoft.Reporting.WebForms;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace ReportViewerForMvc
{
internal static class ReportViewerHelper
{
internal static ReportViewer AnonymousToReportViewer(object obj)
{
try
{
return obj.ToType<ReportViewer>();
}
catch (ArgumentException ex)
{
throw new ArgumentException("Could not convert anonymous object to type ReportViewer", ex);
}
}
internal static LocalReport AnonymousToLocalReport(object obj)
{
try
{
return obj.ToType<LocalReport>();
}
catch (ArgumentException ex)
{
throw new ArgumentException("Could not convert anonymous object to type LocalReport", ex);
}
}
internal static ServerReport AnonymousToServerReport(object obj)
{
try
{
return obj.ToType<ServerReport>();
}
catch (ArgumentException ex)
{
throw new ArgumentException("Could not convert anonymous object to type ServerReport", ex);
}
}
internal static List<ReportParameter> AnonymousToReportParameter(object obj)
{
List<ReportParameter> reportParameters = new List<ReportParameter>();
foreach (KeyValuePair<string, string> keyValuePair in obj.ToDictionary())
{
reportParameters.Add(new ReportParameter(keyValuePair.Key, keyValuePair.Value));
}
return reportParameters;
}
internal static List<ReportDataSource> AnonymousToReportDataSourceList(object obj)
{
List<ReportDataSource> reportDataSourceList = new List<ReportDataSource>();
try
{
if (obj.GetType().IsArray)
{
foreach (var reportDataSource in (IEnumerable)obj)
{
reportDataSourceList.Add(reportDataSource.ToType<ReportDataSource>());
}
}
else
{
reportDataSourceList.Add(obj.ToType<ReportDataSource>());
}
}
catch (ArgumentException ex)
{
throw new ArgumentException("Could not convert anonymous object to type ReportDataSource", ex);
}
return reportDataSourceList;
}
private static T ToType<T>(this object obj)
{
if (obj == null)
{
throw new ArgumentNullException("obj", "Value cannot be null.");
}
T instance = Activator.CreateInstance<T>();
foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
{
var property = typeof(T).GetProperty(propertyInfo.Name);
if (property == null)
{
throw new ArgumentException("An attempt was made to set the property '" + propertyInfo.Name + "' that is not found on object type '" + typeof(T).Name + "'");
}
property.SetValue(instance, propertyInfo.GetValue(obj));
}
return instance;
}
private static IDictionary<string, string> ToDictionary(this object obj)
{
IDictionary<string, string> dic = new Dictionary<string, string>();
foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties())
{
dic.Add(propertyInfo.Name, propertyInfo.GetValue(obj).ToString());
}
return dic;
}
}
}

View file

@ -0,0 +1,23 @@
<%@ Page Language="C#" AutoEventWireup="True" CodeBehind="ReportViewerWebForm.aspx.cs" Inherits="ReportViewerForMvc.ReportViewerWebForm" %>
<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body style="margin: 0px; padding: 0px;">
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Assembly="ReportViewerForMvc" Name="ReportViewerForMvc.Scripts.PostMessage.js" />
</Scripts>
</asp:ScriptManager>
<rsweb:ReportViewer ID="ReportViewer1" runat="server"></rsweb:ReportViewer>
</div>
</form>
</body>
</html>

View file

@ -0,0 +1,27 @@
using Microsoft.Reporting.WebForms;
using System;
using System.Web.UI.WebControls;
namespace ReportViewerForMvc
{
/// <summary>
/// The Web Form used for rendering a ReportViewer control.
/// </summary>
public partial class ReportViewerWebForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
BuildReportViewer();
}
private void BuildReportViewer()
{
if (!IsPostBack)
{
ReportViewerForMvc.ReportViewer.ID = ReportViewer1.ID;
ReportViewer1.SetProperties(ReportViewerForMvc.ReportViewer);
}
}
}
}

View file

@ -0,0 +1,42 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ReportViewerForMvc {
public partial class ReportViewerWebForm {
/// <summary>
/// form1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlForm form1;
/// <summary>
/// ScriptManager1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.ScriptManager ScriptManager1;
/// <summary>
/// ReportViewer1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::Microsoft.Reporting.WebForms.ReportViewer ReportViewer1;
}
}

View file

@ -0,0 +1,11 @@
Sys.Application.add_load(function () {
$find("ReportViewer1").add_propertyChanged(viewerPropertyChanged);
});
function viewerPropertyChanged(sender, e) {
if (e.get_propertyName() === "isLoading") {
top.postMessage("", '*'); //Trigger resize.
}
}
//TODO: Get control ID dynamically.

View file

@ -0,0 +1,35 @@
var ReportViewerForMvc = ReportViewerForMvc || (new function () {
var _iframeId = {};
var resizeIframe = function (msg) {
var height = msg.source.document.body.scrollHeight;
var width = msg.source.document.body.scrollWidth;
$(ReportViewerForMvc.getIframeId()).height(height);
$(ReportViewerForMvc.getIframeId()).width(width);
}
var addEvent = function (element, eventName, eventHandler) {
if (element.addEventListener) {
element.addEventListener(eventName, eventHandler);
} else if (element.attachEvent) {
element.attachEvent('on' + eventName, eventHandler);
}
}
this.setIframeId = function (value) {
_iframeId = '#' + value;
};
this.getIframeId = function () {
return _iframeId;
};
this.setAutoSize = function () {
addEvent(window, 'message', resizeIframe);
}
}());
ReportViewerForMvc.setAutoSize();

View file

@ -0,0 +1,27 @@
using System;
using System.Web.UI;
namespace ReportViewerForMvc
{
internal static class WebResourceHelper
{
internal static string GetWebResourceUrl(Type type, string resourceName)
{
string resourceUrl = null;
Page page = new Page();
try
{
resourceUrl = page.ClientScript.GetWebResourceUrl(type, resourceName);
}
catch (ArgumentNullException)
{
//TODO: Validate if IIS is not running. Unit testing fails due basepath is null.
//in the meanwhile do nothing ...like my boss.
}
return resourceUrl;
}
}
}

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Report.Viewer" version="11.0.0.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
</packages>