Below is a Generic SSRS web service reporting method that generates a byte[] perfect for use in an annotation or email attachment. The example method above it shows how to call this method and how to create an annotation attachment.
You can combine this with my post on driving email templates and generating email attachments to create some very powerful solutions. If you need a primer on activity parties see my post on creating activity parties.
Generating SSRS reports by web service is a very valuable tool. I frequently use this to generate custom reports from custom web applications running in iframes such that the report is run with the permissions of the user running the report. To take advantage of this the reports must be run against MS CRM’s filtered views.
To Generate an SSRS report by web service do the following:
1. Add a report execution web reference to your solution. Make sure this link is accessible. The url should be something like the following:
http://<SRS_Server_Name>/ReportServer/ReportExecution2005.asmx
2. Build up the parameters that you need to generate the report.
3. Select the Report Name of your Report
4. Specify the Type of Report
5. Specify the Device information ( formatting )
The example method CallReport() below demonstrates these steps. It in turn calls GenerateSRSbytes which makes the actual web service call.
using System.Net;
using Microsoft.Win32;
using ReportExecutionService;
public class SRSReporting
{
public void CallReport()
{
string reportServiceUrl = "http://<SRS_Server_Name>/ReportServer/ReportExecution2005.asmx";
// Create the Report Service Url from the registry
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\MSCRM", false);
if (key != null)
{
reportServiceUrl = (string)key.GetValue("SQLRSServerURL") + @"/ReportExecution2005.asmx";
}
// Report parameter Name and Value fields are strings.
string reportParameter = "type";
string reportValue = "annual";
// Create as many parameters as you need.
var parameters = new[]
{
new ParameterValue {Name = "entityid", Value = "0031a390-0d42-de11-9aa9-0003ff517b20"},
new ParameterValue {Name = reportParameter, Value = reportValue}
};
// Pathname to the report from Reporting Services, where TestReport is the rdl uploaded using http://<SRS_Server_Name>/Reports
// Make sure that you set the Data Source properly
// Make sure to set security properly
string reportName = "/AutomatedCRMReporting/TestReport";
// Specify what type of report you want to create HTML,PDF, CVS, Excel, Word, XML, MHTML, Image
string reportFormat = "PDF";
// Specify the device information to control the output of your report.
//For device information See http://msdn2.microsoft.com/en-us/library/ms155397.aspx
string deviceInformation = "<DeviceInfo><DpiX>240</DpiX><DpiY>240</DpiY><StartPage>0</StartPage></DeviceInfo>";
// Generate a report in a format for a CRM annotation or email attachment
byte[] generatedReport = GenerateSRSbytes(reportName, parameters, reportFormat, deviceInformation, reportServiceUrl, null, null, null);
// An example attachment created from an SRS report
//var newAnnotation = new annotation
// {
// objectid = CrmTypes.CreateLookup(regardingEntity, regardingId),
// objecttypecode = CrmTypes.CreateEntityNameReference(EntityName.contact.ToString()),
// isdocument = CrmTypes.CreateCrmBoolean(true),
// ownerid = CrmTypes.CreateOwner(EntityName.systemuser.ToString(), ownerId),
// filename = reportFileName,
// documentbody = Convert.ToBase64String(generatedReport),
// filesize = CrmTypes.CreateCrmNumber(generatedReport.Length),
// subject = reportFileName
// };
//service.Create(newAnnotation);
}
/// <summary>
/// Generates an SSRS Report and returns a byte[] for a CRM attachment
/// </summary>
/// <param name="reportPath">Name of the report.</param>
/// <param name="parameters">The parameters.</param>
/// <param name="outputFormat">The output format.</param>
/// <param name="deviceInformation">The device information. See http://msdn2.microsoft.com/en-us/library/ms155397.aspx</param>
/// <param name="ReportServiceUrl"></param>
/// <param name="userName">if null, DefaultNetworkCredentials are used</param>
/// <param name="passWord">if null, DefaultNetworkCredentials are used</param>
/// <param name="domainName"></param>
/// <returns></returns>
public static byte[] GenerateSRSbytes(string reportPath, ParameterValue[] parameters, string outputFormat, string deviceInformation, string ReportServiceUrl, string userName, string passWord, string domainName)
{
string encoding;
string mimeType;
string extension;
string[] streamIDs;
string SessionId;
string historyID = null;
Warning[] warnings;
// By default the Report will run with the permissions of the AD authenticated User.
var rs = new ReportExecutionService.ReportExecutionService
{
Credentials = System.Net.CredentialCache.DefaultNetworkCredentials,
Url = ReportServiceUrl
};
// Impersonate credentials if they are specified.
if (userName != null && passWord != null)
{
if (domainName == null)
{
rs.Credentials = new NetworkCredential(userName, passWord);
}
else
{
rs.Credentials = new NetworkCredential(userName, passWord, domainName);
}
}
// Set timeout in seconds of the report takes a long time.
//rs.Timeout = 600000;
ExecutionHeader execHeader = new ExecutionHeader();
rs.ExecutionHeaderValue = execHeader;
var execInfo = new ExecutionInfo();
execInfo = rs.LoadReport(reportPath, historyID);
rs.SetExecutionParameters(parameters, "en-us");
SessionId = rs.ExecutionHeaderValue.ExecutionID;
// Render Report
return rs.Render(outputFormat, deviceInformation, out extension, out mimeType, out encoding, out warnings, out streamIDs);
}
}
Happy Coding!