none
Custom assembly in Report Viewer with .Net Framework 4 RRS feed

  • Question

  • Hello all,

    I've developed an application on .net Framework 3.5 and I'm currently migrating it on .net Framework 4.

    I'm facing a problem with security policies related to ReportViewer.

    In my application, I'm using a specific .dll to format numbers and this .dll is called by several local reports (.rdlc files). In order for the project to compile, I dutifully copy the .dll in the Common 7\IDE\Private Assemblies directory.

    I also included these two lines of code (which I found on the blog of a development genius, but I don't really understand them) in the form that contains the ReportViewer:

    myReportViewer.LocalReport.ExecuteReportInCurrentAppDomain(Reflection.Assembly.GetExecutingAssembly().Evidence) 
    
    myReportViewer.LocalReport.AddTrustedCodeModuleInCurrentAppDomain("A3I.Adonat.Métier, Version=8.3.0.0, Culture=neutral, PublicKeyToken=null") 
    

    Now these lines of code don't run...

    What should I do ? Is there another way of using a custom .dll in a local report ? I've followed the Microsoft documentation and placed the following line in my App.config :

     <runtime>
       <NetFx40_LegacySecurityPolicy enabled="true"/>
    </runtime>

    but it still doesn't work...

     

    Please help!!

    Wednesday, June 16, 2010 3:18 PM

Answers

  • 3) Ah, I see this is an error compiling the RDLC. Hint: there's a way around putting DLL in the Common7... directory. To do this, 1) change the RDLC's file property from "Build Action=Embedded Resource" to "Build Action=None", then 2) in your code use the LocalReport.ReportPath property to reference the path of the report instead, and then 3) make sure you add a reference to A3I.Adonat.Métier.DLL in your project using Add Reference.

    5) Now, I have not dealt with security critical code before, but check out http://msdn.microsoft.com/en-us/library/stfy7tfc.aspx. A3I.Adonat.Métier.DLL may be decorated or has members that are decorated with SecurityCriticalAttribute. By default, the sandboxed app domain only has Execution permission, which means any code executed within is transparent because of partial trust. You may want to try giving it full trust, like so:

    ReportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(new PermissionSet(PermissionState.Unrestricted));


    Cephas Lin This posting is provided "AS IS" with no warranties.
    Friday, June 25, 2010 4:16 PM
    Moderator

All replies

  • Sygrien,

    Why do you say this issue is related to security policy? What is the error message? Also are there any error messages in your Windows Event logs? What is the version of your .dll? What does it really do? 

     

     


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Thursday, June 17, 2010 8:09 AM
    Moderator
  • Charles,

    The error message is :

    "Report execution in the current AppDomain requires Code Access Security policy, which is off by default in .NET 4.0 and later.  Enable legacy CAS policy or execute the report in the sandbox AppDomain."

    The .dll version is "8.3.0.0". This .dll simply formats hours-minutes. It reads a user parameter (in the SQL server database) and applies formatting accordingly. It would be very cumbersome to do the formatting before sending the data to the report writer because it applies to totals and subtotals.

    Thanks for your help.

    Friday, June 18, 2010 7:20 AM
  • Hi Sygrien,

    From this article, http://msdn.microsoft.com/en-us/magazine/dvdarchive/ee677170.aspx, we can see that .NET 4.0 introduces many changes to the security model. To resolve this issue, you can try enabling CAS policy in your application's app.config file as follows:
    configuration>

       <runtime>

          <!-- enables legacy CAS policy for this process -->

          <NetFx40_LegacySecurityPolicy enabled="true" />

       </runtime>

    </configuration>

    Hope it helps.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Tuesday, June 22, 2010 12:31 PM
    Moderator
  • Thank you Charles,

    If you read carefully my post, you will see that I already tried to re-enable CAS policy. I have placed the "<runtime><NetFx40_LegacySecurityPolicy enabled = "true"/></runtime>" lines both in the app.config of my application and in the app.config of the .dll.

    But I still get this error :

    Report execution in the current AppDomain requires Code Access Security policy, which is off by default in .NET 4.0 and later. Enable legacy CAS policy or execute the report in the sandbox AppDomain

    The exact copy of the <runtime> section of my app.config is :

     <runtime>
       <!-- enables legacy CAS policy for this process -->
       <NetFx40_LegacySecurityPolicy enabled="true" />
      
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
        <assemblyIdentity name="EnvDTE" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0"/>
       </dependentAssembly>
      </assemblyBinding>
    
    </runtime>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
    

     

    What did I miss ?

    Thanks

    Wednesday, June 23, 2010 7:31 AM
  • Warning: The Value expression for the textrun ‘textbox28.Paragraphs[0].TextRuns[0]’ contains an error: Attempt by security transparent method 'ReportExprHostImpl+textbox28_TextBoxExprHost+Paragraph00_ParagraphExprHost+TextRun00_TextRunExprHost.get_ValueExpr()' to access security critical method 'A3I.Adonat.Métier.Fonctions.FormatFlex(Int32)' failed. (rsRuntimeErrorInExpression)

    Hello all,

    I'm running a report which uses a custom .dll and I get the above warning message. All the report fields which use a method in the .dll show "Error"

    What does it mean ? How can I fix this ?

    Thanks

    Wednesday, June 23, 2010 7:57 AM
  • Sygrien,

    Sorry for omitting reading the last part of your original post. Did you enable ClickOnce security settings with partial trust on your application/assembly? Generally for a full trust application, CAS should not be an issue.

    You may try using the method LocalReport.AddFullTrustModuleInSandboxAppDomain() to add your assembly with full trust. Your previous method was not full trust. You can refer to these two articles:
    http://msdn.microsoft.com/en-us/library/microsoft.reporting.winforms.localreport.addfulltrustmoduleinsandboxappdomain.aspx

    This method needs to be used with the CAS configuration together.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help
    Wednesday, June 23, 2010 9:58 AM
    Moderator
  • Charles,

    Thanks for your reply.

    1) No, I haven't deliberately enabled partial trust anywhere. For my information, where is this parameter set ? (ClickOnce ?)

    2) Do you know why, after having modified the app.config file, the application still seems to work with CAS disabled (default behavior in .net Framewok 4)

    3) I tried using the LocalReport.AddFullTrustModuleInSandboxAppDomain method. That was quite a challenge, because this method requires the use of the StrongName class. Anyway, when I run the application, I get another error "Attempt by security transparent method to access security critical method". the full message of the error is "Warning: The Value expression for the textrun ‘textbox28.Paragraphs[0].TextRuns[0]’ contains an error: Attempt by security transparent method 'ReportExprHostImpl+textbox28_TextBoxExprHost+Paragraph00_ParagraphExprHost+TextRun00_TextRunExprHost.get_ValueExpr()' to access security critical method 'A3I.Adonat.Métier.Fonctions.FormatFlex(Int32)' failed. (rsRuntimeErrorInExpression)". Although it looks like a warning, the textbox of the report show a content of "Error".

    4) What do you mean by "This method needs to be used with the CAS configuration together" ?

    Thanks

     

    Wednesday, June 23, 2010 1:21 PM
  • Is there any reason you don't want to do this with the sandboxed app domain? You don't really need to put your assembly in common 7\..., you just need to make sure you add a reference to the DLL in your project. The following lines should suffice:

     

     

    byte[] publicKey = new byte[8] { 0xaa, 0xbb, 0xcc, 0xdd, 0x00, 0x11, 0x22, 0x33 }; (whatever the assembly key is)
    System.Security.Policy.StrongName sn = new System.Security.Policy.StrongName(new System.Security.Permissions.StrongNamePublicKeyBlob(publicKey), "MyLibrary", new Version("1.0.0.0"));
    ReportViewer1.LocalReport.AddFullTrustModuleInSandboxAppDomain(sn);

    ... and whatever permissions the DLL requires need to be added as well...


    Cephas Lin This posting is provided "AS IS" with no warranties.
    • Proposed as answer by Francisco H E Wednesday, October 30, 2019 5:08 PM
    Thursday, June 24, 2010 3:20 AM
    Moderator
  • Hello Cephalin,

     

    Thanks for your reply.

    Yes, I did try to do it the way you recommend. I was able to generate the Strongname as you describe it.

    But I still get a warning (see the bullet #3 in my previous post)  "Attempt by security transparent method to access security critical method". Although it is a simple warning, all the textboxes in the report which use the .dll show an error message. What's your advice ??

    Besides, if I don't put the .dll in the Common 7\..., the project doesn't compile.

    Thursday, June 24, 2010 9:20 AM
  • Somehow I didn't see the your whole conversation with Charles yesterday when I wrote the reponse. It helps to have the context. To run your code in sandboxed app domain, you should remove the CAS legacy tag. This way, ReportViewer will already run in a sandboxed app domain. Then all you need to do is use AddFullTrustModuleInSandboxAppDomain() to add your assembly.

    Don't know why your project doesn't compile. All VS should need is for the assembly to be referenced in your project's References folder in Solutions Explorer. Of course, this step is not automatic and you have to hook it up yourself.


    Cephas Lin This posting is provided "AS IS" with no warranties.
    Thursday, June 24, 2010 3:57 PM
    Moderator
  • Thanks again Cephalin.

    Here is some more context :

    The entire application is composed of 24 different projects (Windows Forms, class libraries, CLR triggers, Windows services, etc)

    The "main" project is a Windows Forms project. It contains 10 local reports (.rdlc files, no fancy stuff) which run locally, no Report Server. This "main" project calls a class library (.dll file) to format data on the forms.  So it's only logical that when the same data is shown on a report, the same .dll provides the same formatting.

    So I want to find a way to call my .dll from a report.

    1) The 24 projects are all in the same solution. The references in Solution Explorer are OK

    2) All projects are signed with the same .snk file. I have written a routine to generate a Strongname for the .dll (Strongname is needed to call the LocalReport.AddFullTrustModuleInSandboxAppDomain). This seems to work. Is there a way for me to check that the .dll is indeed run in the SandboxAppDomain ?

    3) I have to manually copy the .dll to the "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies" directory. Otherwise, the project doesn't compile. I get this message : "Error 1 Error while loading code module: ‘A3I.Adonat.Métier, Version=8.3.0.0, Culture=neutral, PublicKeyToken=3cd3e780e1dc650a’. Details: Could not load file or assembly 'A3I.Adonat.Métier, Version=8.3.0.0, Culture=neutral, PublicKeyToken=3cd3e780e1dc650a' or one of its dependencies. The system cannot find the file specified. C:\Users\JF\Documents\Adonat\Projet Adonat\Adonat\Etats\rptMouvementOpérateur.rdlc"

    4) I have removed the legacy parameter in the app.config file. BTW, I've been facing this problem for two weeks now and this parameter NEVER had any effect.

    5) When I run the report, all the fieds that should be formatted by the .dll appear as "#Error" and the following message shows up in the Immediate window :

    Warning: The Value expression for the textrun ‘textbox28.Paragraphs[0].TextRuns[0]’ contains an error: Attempt by security transparent method 'ReportExprHostImpl+textbox28_TextBoxExprHost+Paragraph00_ParagraphExprHost+TextRun00_TextRunExprHost.get_ValueExpr()' to access security critical method 'A3I.Adonat.Métier.Fonctions.FormatFlex(Int32)' failed. (rsRuntimeErrorInExpression)

    So it seems to me that the .dll is considered "Security Critical" and can't be called by the report which is considered "Security Transparent".

    Question 1 : Why is the .dll considered as "Security Critical" ? Is it because I have applied the AddFullTrustModuleInSandboxAppDomain method ?

    Question 2 : Why is the report considered "Security Transparent" ? All reports are local reports.

    Question 3 : How do I make this work ? May I add Security tags somewhere to allow the report and the .dll to collaborate ?

    Thanks

     

     

    Friday, June 25, 2010 9:15 AM
  • 3) Ah, I see this is an error compiling the RDLC. Hint: there's a way around putting DLL in the Common7... directory. To do this, 1) change the RDLC's file property from "Build Action=Embedded Resource" to "Build Action=None", then 2) in your code use the LocalReport.ReportPath property to reference the path of the report instead, and then 3) make sure you add a reference to A3I.Adonat.Métier.DLL in your project using Add Reference.

    5) Now, I have not dealt with security critical code before, but check out http://msdn.microsoft.com/en-us/library/stfy7tfc.aspx. A3I.Adonat.Métier.DLL may be decorated or has members that are decorated with SecurityCriticalAttribute. By default, the sandboxed app domain only has Execution permission, which means any code executed within is transparent because of partial trust. You may want to try giving it full trust, like so:

    ReportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(new PermissionSet(PermissionState.Unrestricted));


    Cephas Lin This posting is provided "AS IS" with no warranties.
    Friday, June 25, 2010 4:16 PM
    Moderator
  • My dear friend Cephalin :

    THANK YOU !!!!!!!!!!!!!

    This simple line of code (ReportViewer1.LocalReport.SetBasePermissionsForSandboxAppDomain(new PermissionSet(PermissionState.Unrestricted));) put an end to a two-week long tragedy : my app is now working and I can now ship new versions to the customer.

    It may not have been a big deal for you, but trust me, it made a big difference to me !

    Thanks again.

    • Proposed as answer by valke Friday, February 22, 2013 1:22 AM
    Saturday, June 26, 2010 3:01 PM
  • Glad we can help. Thank Charles for helping to debug as well. :)


    Cephas Lin This posting is provided "AS IS" with no warranties.
    Monday, June 28, 2010 3:25 PM
    Moderator
  • Hi,

    Am very new to RDLC, is it possible to use bullets in RDLC file (in VS.NET).

    If yes, Could you please guide me how can i use?



    Thanks in advance.
    Thursday, March 10, 2011 4:00 AM
  • Yes. In the "Report Formatting" toolbar (View/Toolbars/Report Formatting") you can add bullets to your text.
    Wednesday, September 21, 2011 3:55 PM
  • Thank you very much Cephas lin..It resolved my problem also :)

    But I could not find  'A3I.Adonat.Métier.DLL'  anywhere and I think its not require.


    • Edited by mnamdeo Monday, July 16, 2012 3:07 PM
    Monday, July 16, 2012 3:04 PM
  • Thanks Sygrien, i helped me too
    Friday, February 22, 2013 1:22 AM