RichTextBox throws OutOfMemory on Azure

2019-07-23 01:27发布

I'm using RichTextBox to convert a string in RTF to plain text, using this piece of code:

private string ConvertToText(string rtf)
{
    if (string.IsNullOrWhiteSpace(rtf)) return string.Empty;

    if (!rtf.Contains("{\\rtf")) return rtf.Trim();  

    using (var helper = new System.Windows.Forms.RichTextBox())
    {
        helper.Rtf = rtf;
        var plainText = helper.Text;

        if (string.IsNullOrWhiteSpace(plainText)) return string.Empty;

        return "<< Rule in Rich Text Format converted to Plain Text >>\n\n" 
            + plainText 
            + "\n\n<< Rule in Rich Text Format converted to Plain Text >>";
    }
}

It works OK on all developers machines, but it does not work when deployed to an Azure Web Site:

{
"$id"             :"1",
"Message"         :"An error has occurred.",
"ExceptionMessage":"Out of memory.",
"ExceptionType"   :"System.OutOfMemoryException",
"StackTrace"      :"   
    at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)\r\n   
    at System.Drawing.Font.GetHeight()\r\n   
    at System.Drawing.Font.get_Height()\r\n   
    at System.Windows.Forms.Control.get_FontHeight()\r\n   
    at System.Windows.Forms.TextBoxBase.get_PreferredHeight()\r\n   
    at System.Windows.Forms.TextBoxBase.AdjustHeight(Boolean returnIfAnchored)\r\n   
    at System.Windows.Forms.TextBoxBase.set_Multiline(Boolean value)\r\n   
    at System.Windows.Forms.RichTextBox.set_Multiline(Boolean value)\r\n   
    at System.Windows.Forms.RichTextBox..ctor()\r\n   
    at ... "
}

It happens no matter the size of the RTF string. I'm already using the "Copy to Local" property of the System.Windows.Forms reference. Does anyone have experience in dealing with RTF and Azure? Is there an alternative way to convert RTF to plain text?

1条回答
你好瞎i
2楼-- · 2019-07-23 02:07

This is an adapted C# version of this C++ forum link suggested by @Gusman on the comments:

public static string ConvertToText(string rtf)
{
    bool slash = false; //indicates if backslash followed by the space
    bool figure_opened = false; //indicates if opening figure brace followed by the space
    bool figure_closed = false; //indicates if closing brace followed by the space
    bool first_space = false; //the else spaces are in plain text and must be included to the result

    if (rtf.Length < 4) return string.Empty;

    int i = 0;
    i = rtf.IndexOf("\\pard");
    if (i < 1) return "";

    var builder = new StringBuilder();
    for (int j = i; j < rtf.Length - 1; j++)
    {
        char ch = rtf[j];
        char nextCh = rtf[j + 1];

        if (ch == '\\' && nextCh == 'p') // appends \n if \pard, except for first
        {
            if (j > i && j < rtf.Length - 4)
            {
                string fiveChars = rtf.Substring(j, 5);
                if (fiveChars.Equals("\\pard"))
                {
                    builder.Append("\n");
                }
            }
        }

        if (ch == '\\' && nextCh == 'u') // to deal correctly with special characters
        {
            string fourChars = rtf.Substring(j + 2, 4);
            string digits = new string(fourChars.TakeWhile(char.IsDigit).ToArray());
            char specialChar = (char)int.Parse(digits);
            builder.Append(specialChar);
            j += digits.Length + 5;
            continue;
        }

        if (ch == '\\' && nextCh == '{') // if the text contains symbol '{'
        {
            slash = false;
            figure_opened = false;
            figure_closed = false;
            first_space = false;
            builder.Append('{');
            j++;
            continue;
        }
        else if (ch == '\\' && nextCh == '}') // if the text contains symbol '}'
        {
            slash = false;
            figure_opened = false;
            figure_closed = false;
            first_space = false;
            builder.Append('}');
            j++;
            continue;
        }
        else if (ch == '\\' && nextCh == '\\') // if the text contains symbol '\'
        {
            slash = false;
            figure_opened = false;
            figure_closed = false;
            first_space = false;
            builder.Append('\\');
            j++;
            continue;
        }
        else if (ch == '\\') // we are looking at the backslash
        {
            first_space = true;
            slash = true;
        }
        else if (ch == '{')
        {
            first_space = true;
            figure_opened = true;
        }
        else if (ch == '}')
        {
            first_space = true;
            figure_closed = true;
        }
        else if (ch == ' ')
        {
            slash = false;
            figure_opened = false;
            figure_closed = false;
        }

        if (!slash && !figure_opened && !figure_closed)
        {
            if (!first_space)
            {
                builder.Append(ch);
            }
            else
            {
                first_space = false;
            }
        }
    }
    return builder.ToString();
}

It works! =D

查看更多
登录 后发表回答