Skip to main content

Notifications

Announcements

No record found.

Microsoft Dynamics CRM (Archived)

Generate report to PDF using C#

(0) ShareShare
ReportReport
Posted on by 200

Hi All,

I have a webjob that auto send emails periodically, and this needs to attach a report as PDF.
This report is from an .rdl file imported to Dynamics 365 (online).

Most of the samples I saw is via javascript and on-premise, and have not found some example for D365 online via C#.
Question: Is it possible to auto generate it to PDF via C#?

Thank you all in advance.

Regards,
Chid

*This post is locked for comments

  • Moni123 Profile Picture
    Moni123 20 on at
    RE: Generate report to PDF using C#

    I am getting JS block error while retrieving Report Sessions due to MFA .Any idea?

    pastedimage1617408909318v1.png

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Generate report to PDF using C#

    yes, this is working for me using C# that can be encapsulated in CRM action (call it from anywhere JS or job or ETL )

  • Moni123 Profile Picture
    Moni123 20 on at
    RE: Generate report to PDF using C#

    Hi Venky - did you find any resolution on JS block issue?

  • Moni123 Profile Picture
    Moni123 20 on at
    RE: Generate report to PDF using C#

    Were you able to do this Via plugin/console job ?

    I am facing same issues.

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Generate report to PDF using C#

    Hi Venky,

    we're facing the same script (javascript) blocked issue from our end, do you have any update regarding the above code Dalia shared?

    Thanks and regards,

    Mattia

  • VENKY KOLAGANI Profile Picture
    VENKY KOLAGANI 270 on at
    RE: Generate report to PDF using C#

    Thanks Dalia for sharing the code.

    Its working fine in console app after changing the Azure app settings.  If it is possible can you share the token generation logic.

    I have used ADAL in console app, but the issue here is we can not use it in CRM Online.

    1. Verified couple articles with grant_type as 'password'  but those are not working.

    2. Able to get the access token with grant_type as 'cleint_credential' but report session is not rendering as script was blocked.

    Regards,

    Venky

  • Dalia Riad Profile Picture
    Dalia Riad 15 on at
    RE: Generate report to PDF using C#

    Hi VENKY, I have it as a custom CRM step as below (you framework must be > 4.6.2)

    using ITWORX.Reliance.Reliable.Common.Helper;

    using Microsoft.Xrm.Sdk;

    using Microsoft.Xrm.Sdk.Workflow;

    using System;

    using System.Activities;

    using System.Collections.Generic;

    using System.IO;

    using System.Linq;

    using System.Net.Http;

    using System.Net.Http.Headers;

    using System.Runtime.Serialization;

    using System.Runtime.Serialization.Json;

    using System.Text;

    using System.Threading.Tasks;

    namespace CustomSteps

    {

    [DataContract]

    public class ApiTokenResponse

    {

    [DataMember]

    public string access_token { get; set; }

    }

    public class ReportObject

    {

    public string id { get; set; }

    public string iscustomreport { get; set; }

    public string reporttypecode { get; set; }

    public string isScheduledReport { get; set; }

    public string EntitySchemaName { get; set; }

    public string CRM_Filter { get; set; }

    public string reportName { get; set; }

    public string EntityRecordID { get; set; }

    }

    public class ConvertReportToPDF : CodeActivity

    {

    #region params

    [Output("ReportPDF")]

    public OutArgument<string> ReportPDF { get; set; }

    [Input("ReportID")]

    [RequiredArgument]

    public InArgument<string> ReportID { get; set; }

    [Input("ReportName")]

    [RequiredArgument]

    public InArgument<string> ReportName { get; set; }

    [Input("EntitySchemaName")]

    public InArgument<string> EntitySchemaName { get; set; }

    [Input("EntityRecordID")]

    public InArgument<string> EntityRecordID { get; set; }

    [Input("CRMFilter")]

    public InArgument<string> CRMFilter { get; set; }

    #endregion

    protected override void Execute(CodeActivityContext context)

    {

    // Create the context

    IWorkflowContext WFContext = context.GetExtension<IWorkflowContext>();

    if (WFContext == null)

    {

    throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");

    }

    IOrganizationServiceFactory serviceFactory = context.GetExtension<IOrganizationServiceFactory>();

    IOrganizationService service = serviceFactory.CreateOrganizationService(WFContext.UserId);

    ReportObject reportParams = new ReportObject()

    {

    id = ReportID.Get<string>(context),

    reportName = ReportName.Get<string>(context),

    EntitySchemaName = EntitySchemaName.Get<string>(context),

    EntityRecordID = EntityRecordID.Get<string>(context),

    CRM_Filter = CRMFilter.Get<string>(context)

    };

    formatReportParams(reportParams);

    CallIntermediate(service, context, ReportPDF, reportParams);

    }

    private void formatReportParams(ReportObject reportParams)

    {

    reportParams.id = formatIDBrackets(reportParams.id);

    reportParams.EntityRecordID = formatIDBrackets(reportParams.EntityRecordID);

    reportParams.iscustomreport = "true";

    reportParams.reporttypecode = "1";

    reportParams.isScheduledReport = "false";

    if (string.IsNullOrEmpty(reportParams.CRM_Filter)

    && !string.IsNullOrEmpty(reportParams.EntitySchemaName)

    && !string.IsNullOrEmpty(reportParams.EntityRecordID))

    {

    if (reportParams.EntitySchemaName == "salesorder")

    {

    reportParams.CRM_Filter = "<ReportFilter><ReportEntity paramname=\"CRM_FilteredSalesOrder\" donotconvert=\"1\"><fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"false\"><entity name=\"salesorder\"><all-attributes/><filter type=\"and\"><condition attribute=\"salesorderid\" operator=\"eq\" value=\"" + reportParams.EntityRecordID + "\"/></filter></entity></fetch></ReportEntity></ReportFilter>";

    }

    }

    }

    private string formatIDBrackets(string id)

    {

    if (!string.IsNullOrEmpty(id))

    {

    id = id.Replace("{", "").Replace("}", "");

    return "{" + id + "}";

    }

    return null;

    }

    private static async void CallIntermediate(IOrganizationService service, CodeActivityContext context, OutArgument<string> ReportPDF, ReportObject reportParams)

    {

    await GenerateResportAsPDF_Async(service, context, ReportPDF, reportParams);

    }

    public static async Task<string> GenerateResportAsPDF_Async(IOrganizationService service, CodeActivityContext context, OutArgument<string> ReportPDF, ReportObject reportParams)

    {

    try

    {

    string organizationUrl = "yourenv.crm.dynamics.com";

    string tenantID = "a1a5384f-f0fc-4df9-9f37-000000000000";

    string clientId_applicationId = "2e4ee484-8654-4fdf-a629-000000000000";

    string OAuth2_0Token_Endpoint = "login.microsoftonline.com/" + tenantID + "/oauth2/token";

    string username = "user@domain.com";

    string password = "pwd";

    string clientSecret = "scrt";

    string accessToken = CRMAuthentication.GetAuthToken(organizationUrl, tenantID, clientId_applicationId, OAuth2_0Token_Endpoint, username, password, clientSecret);

    //********** Request 2 to run the resport**********//

    HttpClient _httpClient2 = new HttpClient();

    _httpClient2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    _httpClient2.Timeout = new TimeSpan(0, 2, 0);

    _httpClient2.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));

    //Account Distribution OOB report sample

    HttpRequestMessage request2 = new HttpRequestMessage(HttpMethod.Post, organizationUrl + "/CRMReports/rsviewer/reportviewer.aspx");

    var lst = new List<KeyValuePair<string, string>>

    {

    new KeyValuePair<string, string>("id",reportParams.id),

    new KeyValuePair<string, string>("iscustomreport",reportParams.iscustomreport),

    new KeyValuePair<string, string>("reporttypecode",reportParams.reporttypecode),

    new KeyValuePair<string, string>("reportName",reportParams.reportName),

    new KeyValuePair<string, string>("isScheduledReport",reportParams.isScheduledReport),

    new KeyValuePair<string, string>("CRM_Filter",reportParams.CRM_Filter)

    };

    var formUrlEncodedContent = new FormUrlEncodedContent(lst);

    request2.Content = formUrlEncodedContent;

    using (Task<HttpResponseMessage> response = _httpClient2.SendAsync(request2))

    {

    string resultValue = await response.Result.Content.ReadAsStringAsync();

    var x = resultValue.LastIndexOf("ReportSession=");

    var y = resultValue.LastIndexOf("ControlID=");

    string ReportSession = resultValue.Substring(x + 14, 24);

    string ControlID = resultValue.Substring(y + 10, 32);

    //********** Request 3 to save the generated report as PDF**********//

    var pth = organizationUrl + "/Reserved.ReportViewerWebControl.axd?ReportSession=" + ReportSession + "&Culture=1033&CultureOverrides=True&UICulture=1033&UICultureOverrides=True&ReportStack=1&ControlID=" + ControlID + "&OpType=Export&FileName=Public&ContentDisposition=OnlyHtmlInline&Format=PDF";

    HttpClient _httpClient3 = new HttpClient();

    _httpClient3.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    _httpClient3.Timeout = new TimeSpan(0, 2, 0);

    _httpClient3.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));

    HttpRequestMessage request3 = new HttpRequestMessage(HttpMethod.Get, pth);

    using (Task<HttpResponseMessage> response3 = _httpClient2.SendAsync(request3))

    {

    //System.IO.Stream resultValue3 = await response3.Result.Content.ReadAsStreamAsync();

    var resultValue3 = await response3.Result.Content.ReadAsByteArrayAsync();

    string encodedData = Convert.ToBase64String(resultValue3);

    ReportPDF.Set(context, encodedData);

    }

    }

    }

    catch (Exception ex)

    {

    throw ex;

    }

    return "";

    }

    }

    }

  • VENKY KOLAGANI Profile Picture
    VENKY KOLAGANI 270 on at
    RE: Generate report to PDF using C#

    Hi Dalia,

    Can you share the complete code of console app.

    Thanks!!

  • PabloCRP Profile Picture
    PabloCRP 1,086 on at
    RE: Generate report to PDF using C#

    --Hi, partner i've just tried your solution and  i've  some questions I really apreciate if you could help me , btw  i tried this in JS and works well, ok but i tried  to use this in c# .net because i think doing this in c# like a plugin could be more pro, so unafortunelly it does not work where? on "step 2",  then i tried like fiddler an i get the url  ....

    https://[myorg]/Reserved.ReportViewerWebControl.axd?ReportSession=zot3ee3xpwnizyn1pddpie3g&Culture=2058&CultureOverrides=True&UICulture=3082&UICultureOverrides=True&ReportStack=1&ControlID=d551cbfc672b492b99ca99e2fe8ca99a&RSProxy=http%3a%2f%2fbn1crmp665agl01%2freportserver&OpType=Export&FileName=THEAWESOMEREPORT&ContentDisposition=OnlyHtmlInline&Format=PDF

    --and copying and pasting this in the URL like chrome it  downloads the report but doing the same in postman client it doesn't or well the response says that "Script is disabled. Click Submit to continue." that similar response happend on Step 2 when i get the resultValue. Is this workaround still availible to ? i'm using Dynamics CE v9.1. I'm looking forward to your response.

    thanks, regards....

  • Dalia Riad Profile Picture
    Dalia Riad 15 on at
    RE: Generate report to PDF using C#

    Hi Arghya, I have used fiddler to get all the info

    you can open your report in the browser , generate and then save it as PDF , all your actions will be  tracked in fiddler with its paramenter

    what I did was just simulation all backend calls tracked by fiddler.

    please let me know and i can provide some screen

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Suggested Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,280 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,253 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans