部署后Az​​ure功能无法正常运行

时间:2019-05-14 06:10:32

标签: azure azure-functions barcode

我具有条形码功能,该功能在本地环境下效果很好。但是,将条形码部署到天蓝色后,随机请求无法正常工作。

我已经下载了演示EAN13条码字体,并尝试使用以下代码来打印条码。

如果我在本地环境中请求多个请求,则它可以正常工作。部署到Azure之后,当我们一次请求多个请求时,它会随机返回错误的条形码。例如,失败案例10个请求中有3个。

c#条形码功能

     public string GenerateBarCodeFont(string barCodeTextP, out bool isError, int widthP = 0, int heightP = 0, string fontNameP = "", int fontP = 0)
                {
                    isError = false;
     aa:
     try
                {
                    fontArray = new byte[0];
                    dataLength = 0;

                    if (widthP == 0)
                        widthP = 1;

                    if (heightP == 0)
                        heightP = 1;

                    if (fontP == 0)
                        fontP = 16;
                  fontArray = VLCEANThirtenBarCode.Properties.Resources.UPCEAN_0;
                    dataLength = VLCEANThirtenBarCode.Properties.Resources.UPCEAN_0.Length;
                    barCodeText = EAN13(barCodeTextP);

                    IntPtr destination = Marshal.AllocCoTaskMem(dataLength);

                    Marshal.Copy(fontArray, 0, destination, dataLength);
                    uint pcFonts = 0;
                    AddFontMemResourceEx(destination, (uint)fontArray.Length, IntPtr.Zero, ref pcFonts);
                    PrivateFontCollection fonts = new PrivateFontCollection();
                    fonts.AddMemoryFont(destination, dataLength);
                    Marshal.FreeCoTaskMem(destination);
                    this.ff = fonts.Families[0];
                    int num3 = heightP * 2;
                    int num5 = Convert.ToInt32((double)(Convert.ToDouble(widthP) * 1.5));
                    int num6 = (heightP * 100) / 90;
                    Font font = new Font(this.ff, (float)fontP);
                    PointF point = new PointF(2f, 2f);
                    Bitmap bitmap = new Bitmap(widthP, heightP, PixelFormat.Format24bppRgb);
                    bitmap.SetResolution((float)num6, (float)num6);
                    Graphics graphics = Graphics.FromImage(bitmap);
                    graphics.FillRectangle(new SolidBrush(Color.White), 0, 0, widthP, heightP);
                    graphics.DrawString(barCodeText, font, new SolidBrush(Color.Black), point);
                    using (MemoryStream stream = new MemoryStream())
                    {
                        bitmap.Save(stream, ImageFormat.Png);
                        byte[] inArray = stream.ToArray();
                        Convert.ToBase64String(inArray);
                        barCodeText = Convert.ToBase64String(inArray, 0, inArray.Length);
                    }
                    bitmap.Dispose();
        }
                    catch (Exception ex)
                    {
                        if (ex.Message == "A generic error occurred in GDI+.")
                            goto aa;
                        isError = true;
                        return ex.Message;
                    }
                    return barCodeText;
                }

EAN13 BarCodefont逻辑

public string EAN13(string bcP)
        {
            string s = "", suppl = "", TempStrL = "";
            int CountryFlagL = 0;

            switch (bcP.Length)
            {
                case 12:
                case 13:
                    s = bcP.Substring(0, 12) + CheckDigit(SYMB_EAN13, bcP.Substring(0, 12));
                    break;
                case 14:
                case 15:
                    s = bcP.Substring(0, 12) + CheckDigit(SYMB_EAN13, bcP.Substring(0, 12));
                    suppl = AddOn(bcP.Substring(bcP.Length - 2));
                    break;
                case 17:
                case 18:
                    s = bcP.Substring(0, 12) + CheckDigit(SYMB_EAN13, bcP.Substring(0, 12));
                    suppl = AddOn(bcP.Substring(bcP.Length - 5));
                    break;
            }

            TempStrL = GetChar(digitsOnly, s.Substring(0, 1));//
            TempStrL = TempStrL + "{{{{{";
            TempStrL = TempStrL + "|";

            CountryFlagL = Convert.ToInt32(s.Substring(0, 1));//

            for (int i = 1; i <= 6; i++)
            {
                if (GetParity(SYMB_EAN13, i - 1, CountryFlagL) == "A")//
                    TempStrL = TempStrL + GetChar(charsetA, s.Substring(i, 1));//
                else
                    TempStrL = TempStrL + GetChar(charsetB, s.Substring(i, 1));//
            }

            TempStrL = TempStrL + "{" + "|" + "{";

            for (int i = 8; i <= 13; i++)
            {
                TempStrL = TempStrL + GetChar(charsetC, s.Substring(i - 1, 1));
            }

            TempStrL = TempStrL + "|";

            if (suppl.Length > 0)
                TempStrL = TempStrL + "}" + suppl;


            return TempStrL;
        }

        protected string AddOn(string bcP)
        {
            string parL, ParSectionL = "", TempstrL;
            int TotalL = 0, intbcL, MultiplierL, PositionL, CounterL = 0, SectLengthL;


            switch (bcP.Length)
            {
                case 2:
                    parL = "AA" + "AB" + "BA" + "BB";
                    intbcL = Convert.ToInt32(bcP);
                    TotalL = intbcL % 4;
                    ParSectionL = parL.Substring(TotalL * 2, 2);
                    break;
                case 5:
                    parL = "BBAAA" + "BABAA" + "BAABA" + "BAAAB" + "ABBAA" + "AABBA" + "AAABB" + "ABABA" + "ABAAB" + "AABAB";
                    for (int i = 1; i <= 5; i++)
                    {
                        MultiplierL = 3;
                        if (i % 2 == 0)
                            MultiplierL = 9;

                        intbcL = Convert.ToInt32(bcP.Substring(i - 1, 1));
                        TotalL = TotalL + MultiplierL * intbcL;
                    }
                    PositionL = (TotalL % 10) * 5;
                    ParSectionL = parL.Substring(PositionL, 5);
                    break;
            }

            TempstrL = "m";
            SectLengthL = ParSectionL.Length;

            for (int i = 1; i <= SectLengthL; i++)
            {
                if (ParSectionL.Substring(i - 1, 1) == "A")
                    TempstrL = TempstrL + GetChar(CharsetASupp, bcP.Substring(i - 1, 1));
                else
                    TempstrL = TempstrL + GetChar(CharsetBSupp, bcP.Substring(i - 1, 1));

                if (i < SectLengthL)
                    TempstrL = TempstrL + "n";
            }

            return TempstrL;
        }

        protected string CheckDigit(int SymbologyL, string c)
        {
            string s = "";
            int NumDigitsL = 0, intc = 0, cd;

            decimal TotalL = 0;

            switch (SymbologyL)
            {
                case SYMB_UPCA:
                    NumDigitsL = 11;
                    break;
                case SYMB_EAN13:
                    NumDigitsL = 12;
                    break;
                case SYMB_EAN8:
                    NumDigitsL = 7;
                    break;
            }

            for (int i = 1; i <= NumDigitsL; i++)
            {
                if (((NumDigitsL + 1 - i) % 2) == 0)
                {
                    string str = c.Substring(i - 1, 1);
                    intc = Convert.ToInt32(str);

                    TotalL = TotalL + 1 * intc;
                }
                else
                {
                    string str = c.Substring(i - 1, 1);
                    intc = Convert.ToInt32(str);

                    TotalL = TotalL + 3 * intc;
                }
            }

            cd = 10 - Convert.ToInt32(TotalL % 10);
            if (cd == 10)
                cd = 0;

            return cd.ToString();
        }

        protected string GetChar(string c, string DigitP)
        {
            int intDigitL = Convert.ToInt32(DigitP);

            return c.Substring(intDigitL, 1);
        }

        protected string GetParity(int SymbologyP, int PositionP, int CodeValP)
        {
            string parL = "", ParityL = "";
            switch (SymbologyP)
            {
                case SYMB_EAN13:
                    parL = "AAAAAA" + "AABABB" + "AABBAB" + "AABBBA" + "ABAABB" + "ABBAAB" + "ABBBAA" + "ABABAB" + "ABABBA" + "ABBABA";
                    break;
                case SYMB_UPCE:
                    parL = "BBBAAA" + "BBABAA" + "BBAABA" + "BBAAAB" + "BABBAA" + "BAABBA" + "BAAABB" + "BABABA" + "BABAAB" + "BAABAB";
                    break;
            }

        ParityL = parL.Substring(CodeValP * 6, 6);
        return ParityL.Substring(PositionP, 1);
    }

**全局变量低于**

[DllImport("gdi32.dll")]
        private static extern IntPtr AddFontMemResourceEx(IntPtr pbfont, uint cbfont, IntPtr pdv, [In] ref uint pcFonts);
        FontFamily ff;
        private string barCodeText = string.Empty;
        byte[] fontArray;
        int dataLength;

        const int SYMB_UPCA = 1, SYMB_EAN13 = 3, SYMB_EAN8 = 4, SYMB_UPCE = 2;
        string CharsetASupp = "+,./:;=?@K", CharsetBSupp = @"LMNOP[\]^_";
        string charsetA = "ABCDEFGHIJ", charsetB = "QRSTUVWXYZ", charsetC = "0123456789", digitsOnly = "qrstuvwxyz";

正确的如下所示

enter image description here

下面显示的是错误的

enter image description here

我已经创建了上述函数的vlcbarcode.dll文件引用,并添加了与refered url相同的azure项目,并写入了下面的函数。

下面是天蓝色函数

[FunctionName("GetBarCodes")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "GetBarCodes/")]HttpRequestMessage req, TraceWriter log)
        {

            log.Info("C# HTTP trigger function processed a request.");

            // Get request body
            VLCBarCodes[] barCodeList = await req.Content.ReadAsAsync<VLCBarCodes[]>();

            List<QueryStringClass> resultList = new List<QueryStringClass>();
            string errorText = "";
            string result = "";
            bool isError = false;

            foreach (var list in barCodeList)
            {
                errorText = "";
                result = "";

                if (string.IsNullOrWhiteSpace(list.BarCodeFontType))
                    errorText = " Bar code Type can not be empty or null";

                if (string.IsNullOrWhiteSpace(list.BarCodeValue))
                    errorText += " Bar code text can not be empty or null";

                if (string.IsNullOrWhiteSpace(list.BarCodeFontHeight))
                    errorText += " Bar code height can not be empty or null";

                if (string.IsNullOrWhiteSpace(list.BarCodeFontWidth))
                    errorText += " Bar code width can not be empty or null";

                if (string.IsNullOrWhiteSpace(list.BarCodeFontSize))
                    errorText += " Bar code font can not be empty or null";

                if (list.BarCodeImageUID == 0)
                    errorText += " Bar Code Image Id can not be empty or null";

                if (string.IsNullOrWhiteSpace(list.BarCodeEntryNo))
                    errorText += " Bar Code entry no can not be empty or null";

                if (!string.IsNullOrWhiteSpace(list.BarCodeFontType) && !string.IsNullOrWhiteSpace(list.BarCodeValue) && !string.IsNullOrWhiteSpace(list.BarCodeFontHeight)
                   && !string.IsNullOrWhiteSpace(list.BarCodeFontWidth) && list.BarCodeImageUID != 0 && string.IsNullOrWhiteSpace(errorText))
                {
                    switch (list.BarCodeFontType)
                    { 
                        case "EAN-13":
                            GenerateEANTBarCode generateEANTBarCode = new GenerateEANTBarCode();
                            result = generateEANTBarCode.GenerateBarCodeFont(list.BarCodeValue, out isError, Convert.ToInt32(list.BarCodeFontWidth), Convert.ToInt32(list.BarCodeFontHeight), "EAN-13", Convert.ToInt32(list.BarCodeFontSize));
                            break;
                        default:
                            isError = true;
                            result = "Please specify the bar code font type";
                            break;
                    }
                    if (isError)
                        resultList.Add(new QueryStringClass { BarCodeEntryNo = list.BarCodeEntryNo, BarCodeImageUID = list.BarCodeImageUID, Type = list.BarCodeFontType, Value = "", ErrorText = result });
                    else
                        resultList.Add(new QueryStringClass { BarCodeEntryNo = list.BarCodeEntryNo, BarCodeImageUID = list.BarCodeImageUID, Type = list.BarCodeFontType, Value = result, ErrorText = "" });

                }
                else
                    resultList.Add(new QueryStringClass { BarCodeEntryNo = list.BarCodeEntryNo, BarCodeImageUID = list.BarCodeImageUID, Type = list.BarCodeFontType, Value = result, ErrorText = errorText });
            }

            return req.CreateResponse(HttpStatusCode.OK, resultList);

        }

QueryStringClass可以从vlcbarcode.dll函数获取结果并返回给最终用户。

 public class QueryStringClass
    {
        public int BarCodeImageUID { get; set; }
        //public Guid Guid { get; set; }
        public string BarCodeEntryNo { get; set; }
        public string Type { get; set; }
        public string Value { get; set; }
        public string ErrorText { get; set; }

    }

VLCBarCodes类是指原始calss字段,用于验证请求并将值发送到.dll文件功能。

public class VLCBarCodes
{
    public int BarCodeImageUID { get; set; }
    public string BarCodeValue { get; set; }
    public string BarCodeFontWidth { get; set; }
    public string BarCodeFontHeight { get; set; }
    public string BarCodeFontType { get; set; }
    public string BarCodeFontSize { get; set; }
    public string BarCodeEntryNo { get; set; }
}

请建议我是否做错了事。

1 个答案:

答案 0 :(得分:2)

在Azure App服务中,大多数GDI32系统调用均被阻止。

所有Azure Web应用程序(以及移动应用程序/服务,WebJob和功能)都在称为沙箱的安全环境中运行。

沙箱通常旨在限制对Windows共享组件的访问。不幸的是,Windows的许多核心组件已被设计为共享组件:注册表,加密和图形子系统,等等。本节概述了在使用这些经常必不可少但共享的组件时所受到的限制。

为了大大减少攻击表面积,沙盒阻止了几乎所有Win32k.sys API的调用,这实际上意味着大多数User32 / GDI32系统调用均被阻止。对于大多数应用程序来说,这不是问题,因为大多数Azure Web Apps不需要访问Windows UI功能(毕竟它们是Web应用程序)。

参考文档:https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox

如果愿意使用相同的代码,则可以将此Azure函数托管在Azure虚拟机中,否则,您可以尝试一些替代方法来生成BAR代码,如this blog.

中所述
相关问题