Use MemoryStream ToArray instead of GetBuffer Method & Save to DOCX document byte Array in C# .NET WCF Service to Avoid File Corruption

I have created a WCF-Service which inserts content into bookmarks in a word document.

In short, the service performs the following actions (some code is intentionally excluded from the example):

// convert incoming array of bytes (the word document) to an aspose document
var fromMemoryStream = new MemoryStream(docByteArray);
var asposeDocument = new Document(fromMemoryStream);

// insert content into bookmarks

// save the aspose document to a memory stream. Save as a docx document
var toMemoryStream = new MemoryStream();
asposeDocument.Save(toMemoryStream, SaveFormat.Docx);

// return the array of bytes
return toMemoryStream.GetBuffer();

My client application receives the returned byte array and writes it to disk. Then it opens the document in Word 2007. Word informs me that there is something wrong with the contents of the document, and it cannot be displayed. It then asks me if I want to fix the contents. I click yes, and the document is displayed.

Is there a bug in the save method when I try to save a document using the docx format? The application is working properly when I work with ordinary word documents in the .doc format. Even when I don’t insert the content into the bookmarks, but just converts the byte array to and from an Aspose word Document object, Word gives me the error message. Therefore, it seems to me that Aspose is somehow making the docx file corrupt.

I hope you are able to help me in solving this issue.

Hi

Thanks for your inquiry. Could you please attach your input and output documents here for testing? I will check the issue and provide you more information.
Best regards,

Hi,

Thank you for your quick reply. I have sent you some example documents in an email. I hope you are able to find out what is going wrong with the docx document.

Hi Erik,

Thank you for additional information. The problem is causes by GetBuffer method. It adds extra empty bytes at the end of the array. The solution is very simple. Just use ToArray method instead of GetBuffer. Please see the following code:

// Return the array of bytes
return toMemoryStream.ToArray();

Best regards,

Excellent news! Thank you so much for your help. The simplicity of the solution should have made me embarrassed, but I choose not to be.

@Alexey Noskov!
I have the same problem and I has send you a mail!
Thank for your help!
Here is my fn:

private void SearchAndReplace()
{
    string filePath = @"C:\tmp\EVN.docx";

    FileStream fileStream = File.OpenRead(filePath);
           
        //create new MemoryStream object
        MemoryStream memStream = new MemoryStream();
        memStream.SetLength(fileStream.Length);
        //read file to MemoryStream
        fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
           


    //Document doc = new Document(filePath);
    Document doc = new Document(memStream);
    NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);

    bool DocumentNO = false;
    bool DocumentDate = false;
    bool DocumentNoAndDate = false;
    string SoKyHieu = "Số: xxx/yyy";
    string NgayVanBan = String.Format("Hà Nội, ngày {0} tháng {1} năm {2}", DateTime.Now.Day, DateTime.Now.Month, DateTime.Now.Year);

    int i = 0;
    foreach (Paragraph para in paragraphs)
    {
        if (i > 15)
            return;
        else
        {
            i++;
            string content = para.Range.Text;
            //1. Trường hợp: Số, ngày, tháng, năm cùng thuộc một paragraph
            if (!DocumentNoAndDate)
            {
                int idxOfNo = content.IndexOf("số", StringComparison.OrdinalIgnoreCase);
                int idxOfDay = content.IndexOf("ngày", StringComparison.OrdinalIgnoreCase);
                int idxOfMonth = content.IndexOf("tháng", StringComparison.OrdinalIgnoreCase);
                int idxOfYear = content.IndexOf("năm", StringComparison.OrdinalIgnoreCase);

                if ((idxOfNo + idxOfDay + idxOfMonth + idxOfYear) > 0)
                {
                    string mySpace = ""; //Khoảng trống giữa SÔ và Ngày tháng năm
                    for (int j = 0; i < 100; j++)
                        mySpace += " ";
                    string rpString = String.Format("Số: {0}{1}Hà Nội, ngày {2} tháng {3} năm {4}", SoKyHieu, mySpace, DateTime.Now.Day, DateTime.Now.Month, DateTime.Now.Year);
                    doc.Save(memStream,SaveFormat.Docx );
                }
            }

            //2. Trường hợp: Số và ngày tháng năn nằm khác paragraph
            if (!DocumentNO)
            {
                if (content.Contains("Số") || content.Contains("số"))
                {
                    DocumentNoAndDate = true;
                    DocumentNO = true;

                    string temp = para.Range.Text.Substring(0, para.Range.Text.Length - 1);
                    para.Range.Replace(new Regex(temp), SoKyHieu);
                    DocumentNO = true;
                }
            }

            if (!DocumentDate)
            {
                int idxOfDay = content.IndexOf("ngày", StringComparison.OrdinalIgnoreCase);
                int idxOfMonth = content.IndexOf("tháng", StringComparison.OrdinalIgnoreCase);
                int idxOfYear = content.IndexOf("năm", StringComparison.OrdinalIgnoreCase);

                if (idxOfDay * idxOfMonth * idxOfYear > 0)
                {
                    string temp = para.Range.Text.Substring(0, para.Range.Text.Length - 1);
                    para.Range.Replace(new Regex(temp), NgayVanBan);
                    DocumentDate = true;
                }
            }
            if (DocumentNO && DocumentDate)
            {
                doc.Save(memStream, SaveFormat.Docx);
                FileStream outStream = File.OpenWrite(@"C:\tmp\test1.docx");
                memStream.WriteTo(outStream);
                outStream.Flush();
                outStream.Close();
            }
        }
    }
}

I found!

// After load stream data
Document mydocx = new Document(StreamData)
// I must create a temporary
MemoryStream myStream = new MemoryStream()
// Do everything...
// At the Save, I did
mydocx.Save(myStream, docx) //Importance!
// and get the save data
StreamData = myStream;
// I get no error from "StreamData"

Hi Nguyen,

Thanks for your inquiry. Its great you were able to find what you were looking for. Please let us know any time you have any further queries.

Best regards,