0

SSRS report in VS2015 using a custom function to convert a value to barcode image using zxing.dll. I found this article Generate barcode using Visual Studio local report or SSRS which is essentially identical to what I'm trying to do and have followed it. When I preview the report, it produces the warnings below and the image shows the red-x. I can deploy the report but no images appear in the related columns. The image is set with the correct mime type (image/bmp) but I've tried others with the same results.

NOTE: I've searched for and read several articles that helped me make progress but can't seem to resolve this issue.

The complete errors are:

[rsRuntimeErrorInExpression] The Value expression for the image ‘ImageFromFunction’ contains an error: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

[rsInvalidDatabaseImageProperty] The value of the ImageData property for the image ‘ImageFromFunction’ is “=Code.TextToBarcode128Bmp(Fields!barcode_value.Value)”, which is not a valid ImageData.

I have a WPF where this same code (in C#) works fine. There is just something about using it in SSRS that it doesn't like. The first message seems to indicate that it is a permissions/version kind of thing. I know that SSRS is .NET 2.0. I've set my reference to System.Drawing to 2.0 versions and copied over the 2.0 version of zxing.dll to the server.

It looks like it is attempting to get security permissions (probably for the zxing.dll?) but is unable to reach System.Security.Permissions.SecurityPermission?

References

zxing, Version=0.15.0.0, Culture=neutral, PublicKeyToken=4e88037ac681fe60
System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

I tried added a reference to the 2.0 version of System.Security but it still produced the same error.

This is the custom function:

Public Function TextToBarcode(ByVal text As String) As Byte()

Dim writer As New ZXing.BarcodeWriter()
writer.Format = ZXing.BarcodeFormat.CODE_128
writer.Options = New ZXing.Common.EncodingOptions
writer.Options.Width = 125
writer.Options.Height = 100

Dim bmp As System.Drawing.Bitmap = writer.Write(text)

Dim ms AS System.IO.MemoryStream = new System.IO.MemoryStream()
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp)

Dim imagedata as byte()
imagedata = ms.GetBuffer()

Return imagedata

End Function

UPDATE

I followed the steps in the article SSRS: System.Security.Permissions.SecurityPermission (Thanks, Michael and Superman) which is based upon this article How to use custom assemblies or embedded code in Reporting Services

On the server, I added zxing.dll to the GAC from its location in D:\Program Files\Microsoft SQL Server\MSRS12.MSSQLSERVER\Reporting Services\ReportServer\bin

On the server, I added a CodeGroup to D:\Program Files\Microsoft SQL Server\MSRS12.MSSQLSERVER\Reporting Services\ReportServer\rssrvpolicy.config:

<CodeGroup
    class="UnionCodeGroup"
    version="1"
    PermissionSetName="FullTrust"
    Name="ZXingCodeGroup"
    Description="Code group for ZXing">
    <IMembershipCondition
        class="UrlMembershipCondition"
        version="1"
        Url="D:\Program Files\Microsoft SQL Server\MSRS12.MSSQLSERVER\Reporting Services\ReportServer\bin\zxing.dll"
    />
</CodeGroup>

And I restarted Reporting Services. No change in behavior: Running deployed report produces no errors but does not display the barcode.

On the VS dev system, I then added the CodeGroup to C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PrivateAssemblies\RSPreviewPolicy.config and closed and re-opened Visual Studio. No change in behavior: Preview of report shows same warnings and fails to display the barcode.

UPDATE

I've confirmed this is some kind of permissions issue. By commenting the line that does the ZXing.BarcoderWriter.Write() call it no longer produces this error. In fact, by replacing the function body with code that populates a byte array from image data (below), it successfully displays the image:

Public Function getBarCodeHorizontal(ByVal text1 As String) As Byte()

Dim text as String = "89504E470D0A1A0A0000000D494844520000009600000028080200000093A394B0000000017352474200AECE1CE90000000467414D410000B18F0BFC6105000000097048597300000EC300000EC301C76FA8640000026549444154785EED9AB16EDB400C864F7D112BC892C10F5103196474CD1B548F20C32FE1B1A3FC065D8B6A28203F84072F46EC2751792475C79364C0E822B1E0372824EF3FDAB93FC7C041B2AEEBDC145996C1135621204D0888C934EC0A155CE46E04C9C293AB424F6229A3546A085A22821EE24701E9A942C84AD00C0461952AC0584FABB2EE758894510ACF81009EA1422910768DB748BEF057432D66A17ACC42F59885EA310BD56316AAC72C548F59A81EB3503D66A17ACC42F59885EA310BD56316AAC72C548F59A81EB3503D66A17ACC42F59885EA310BD56316AAC72C544FF21F8F8646EC16AAC72C54CFFF61E169976D8F774EFE9DFB719BED4E9CA8C16EA17ACC42F52CCA4298878C188B7EBA31E9B00CEAEDF1CA254FD0F3484C87ACC8E2AB0D1AA7133599AEC3E64B603916C2E96CCEF50D3EE4745DBB2E733C2428E6E5BAC5E2AD765C05E0FC378EEADDFE521EA8EAEBACBFD5E70D8ABF7EAB9A9F7FD8A2D3AF43F1F1BEF2D16E73A8A8415B35E58F672C19375F04F84D2C805B5D383ED2C8A018D3B67205DB0DF83AA5A21EC5107131DDD61394E32089279BCFCF626EE1E7A529DE5E3879C0EA75EDCE57B850F7EB994B88AF079A32C75197970D89DDEAFDC3E13D8C7710E9A7A2573EC9B8F9FC2CC6C297B7A2B97C72F200EFDCFA152C483C1B20AFD9EFEFE8177B080E567BAAA07DF9658F2A7FA59E64A2F9FCF0FB991F7F90724E618CA7DB4F2C186449DCAB7DDC275123D5BE0F20669F588DDBFDAB0D37CB77F0A0F9CC2CC742000F9388E7836748F49E11415DD4B5F81D27CA429DFC2C7862DBAAED17FD57D684656C1E364E379F17FB33B77AECA3BD7ACC42E538F7178726B2F89D7D5EF80000000049454E44AE426082"

Dim bytes As Byte() = New Byte(text.Length \ 2 - 1) {}
Dim b as Byte

For i As Integer = 0 To text.Length - 1 Step 2
    bytes(i \ 2) = Byte.Parse(text(i).ToString() & text(i + 1).ToString(), System.Globalization.NumberStyles.HexNumber)
Next

Return bytes

End Function

UPDATE

I tried changing the CodeGroup on the server to Strong using the zxing.dll public key token, but no improvement:

<CodeGroup
    class="UnionCodeGroup"
    version="1"
    PermissionSetName="FullTrust"
    Name="ZXingCodeGroup"
    Description="Code group for ZXing">
    <IMembershipCondition
        class="StrongNameMembershipCondition"
        version="1"
        PublicKeyBlob="4e88037ac681fe60"
    />
</CodeGroup>
AdvApp
  • 1,094
  • 1
  • 14
  • 27
  • I can only give you some hints, not a real solution but perhaps it will point you in the right direction. If you search at stackoverflow or the whole internet for "SSRS" and "System.Security.Permissions.SecurityPermission" you will find a lot of results. Most of them are saying that the trust level need to be set for the assembly. Here is one of the links http://spman219.blogspot.de/2014/01/ssrs-systemsecuritypermissionssecurityp.html And another one from stackoverflow: https://stackoverflow.com/questions/32428/how-do-i-resolve-a-system-security-securityexception-with-custom-code-in-ssrs – Michael Jun 02 '17 at 06:50
  • Thank you for those links. Didn't find those in my searches though found some similar ones. I have updated my OP with the results of following those ideas. – AdvApp Jun 02 '17 at 15:18
  • I've confirmed the issue is the ZXing.BarcodeWriter.Write() call. If that is commented out, the security permission error goes away. Of course, the function still doesn't work. See the 2nd update. – AdvApp Jun 02 '17 at 17:12
  • Found this article which outlines the whole process: https://joyfulcraftsmen.wordpress.com/2015/04/27/setting-security-policy-for-custom-assembly-in-ssrs-2014-sharepoint-integrated-mode/ – AdvApp Jun 02 '17 at 18:46
  • But, still haven't been able to resolve this. Very frustrating... – AdvApp Jun 05 '17 at 15:38
  • PublicKeyBlob= "0024000004800000140100000602000000240000525341310008000001000100014c9a01956f13a339130616473f69f975e086d9a3a56278936b12c48ca45a4ddfee05c21cdc22aedd84e9468283127a20bba4761c4e0d9836623fc991d562a508845fe314a435bd6c6ff4b0b1d7a141ef93dc1c62252438723f0f93668288673ea6042e583b0eed040e3673aca584f96d4dca19937fbed30e6cd3c0409db82d5c5d2067710d8d86e008447201d99238b94d91171bb0edf3e854985693051ba5167ca6ae650aca5dd65471d68835db00ce1728c58c7bbf9a5d152f491123caf9c0f686dc4e48e1ef63eaf738a12b3771c24d595cc5a5b5daf2cc7611756e9ba3cc89f08fb9adf39685bd5356858c010eb9aa8a767e5ef020408e0c9746cbb5a8" /> – Michael Sep 14 '17 at 05:35
  • And the attribute [assembly: AllowPartiallyTrustedCallers] needs to be added to the zxing assembly. – Michael Sep 14 '17 at 05:36

1 Answers1

1

Ohh that's a good one..

Did a lot of digging and debugging (if you can call that debugging - I put return statements into the ZXing code, and watched when it would bring up that error)

One thing that is different in my setup than yours: I am using a custom DLL to interact with zxing.dll.

It boils down to the way they put pixel-data into a bitmap:
https://github.com/micjahn/ZXing.Net/blob/eef88ee53ced1035eade39f44544aa955d2db6b6/Source/lib/renderer/BitmapRenderer.cs#L169

The Workaround is to convert it manually:

public static string Test()
    // Don't let ZXing handle the conversion to a bitmap -> give me raw pixel data
    var writer = new BarcodeWriterPixelData { Format = BarcodeFormat.DATA_MATRIX };

    var result = writer.Write("Test123");

    Bitmap bmp = new Bitmap(result.Width, result.Height);

    int bpp = 32;
    for (int y = 0; y < result.Height; y++)
    {
        for (int x = 0; x < result.Width; x++)
        {
            int i = ((y * result.Width) + x) * (bpp / 8);
            if (bpp == 32) // in this case you have 4 color values (red, green, blue,alpha)
            {
                // first byte will be red, because you are writing it as first value
                byte r = result.Pixels[i];
                byte g = result.Pixels[i + 1];
                byte b = result.Pixels[i + 2];
                byte a = result.Pixels[i + 3]; // Alpha?
                Color color = Color.FromArgb(r, g, b);
                bmp.SetPixel(x, y, color);
            }

        }
    }

    return GetBase64(bmp);
}

public static string GetBase64(Image image)
{
    using (MemoryStream m = new MemoryStream())
    {
        image.Save(m, ImageFormat.Png);
        byte[] imageBytes = m.ToArray();
        return Convert.ToBase64String(imageBytes);
    }
}

Source (slightly modified): https://stackoverflow.com/a/16130425/11829240

Also be aware, that you maybe need to build it yourself to insert [assembly:AllowPartiallyTrustedCallers] into AssemblyInfo.cs

The perfect solution would be to generate a SVG, but SSRS doesn't like that.

More to read on that Bitmap.LockBits Topic:
https://www.codeproject.com/Articles/625868/LockBits-Alternative-SecurityException-Workaround

Also found the following:

Hi,

I'm trying to create a Barcode in CRM 2011 (On Premises) Reports. Unfortunately this isn't possible due to Sandbox and various other issues. I've tried a few methods but nothing works.

So my approach now, is to create a c# plugin that generates the barcode image when a record is created, and store the image byte as a string, and then use Convert.FromBase64String in the report to display the barcode image. This method should then hopefully work...

However, after days of trying, I'm stuck with an issue with Permission Security

System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

, and have debugged to a section in the Render that doesn't work / compatible (for CRM 2011..!)

var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);

So my question is: Is there a way to do this without Lockbits ?
Any help here would be greatly received.

Unfortunately the Links is dead: http://zxingnet.codeplex.com/discussions/584679

EDIT: Actually dug it up, Archive of an Archive..
https://web.archive.org/web/20210303162237/https://archive.codeplex.com/?p=zxingnet
Click on discussions and Search for Alternative to LockBits due to Security issues

Codeplex-Archive-Download (zip):
https://web.archive.org/web/20210701004220/https://codeplexarchive.blob.core.windows.net/archive/projects/ZXingNet/ZXingNet.zip

bergerb
  • 71
  • 7