BoldSign®Effortlessly integrate e-signatures into your app with the BoldSign® API. Create a sandbox account!
I have a strange issue using the Document Editor with MS Word files that I hope someone can point me in the right direction to solve. My use case is loading a Word document into the browser from a server, allowing the user to edit the document, then saving the changes back to the server.
In principal, this mostly works. However, my problem is that when saving the document on the server, if it overwrites an existing file, the file becomes corrupted and can't be opened either by the Document Editor, or MS Word. If I try to open it, the error I get is "Zip exception. Can't find local header signature - wrong file format or file is corrupt.".
If I open an existing file, edit it, then delete it from the server before saving it, a new file is created that does not have any issues. Likewise, if I save the edited document with a different name, a new file is again created with no issues. The problem only occurs when saving the changes back over an existing document.
This happens even with a brand new, blank Word document. I have updated my NuGet packages and JS CDN links to the latest version (26.2.8).
This is my javascript for uploading the document:
$("#SaveDocument").on("click", function () {
$.post({
url: "/assessmentreports/savereport/" + document.getElementById("assessment-id").value,
contentType: "application/json; charset=utf-8",
data: JSON.stringify(documentEditor.serialize()),
headers: { 'RequestVerificationToken': $("input[name = __RequestVerificationToken]").val() }
}).done(function () {
alert("Report saved.");
}).fail(function (xhr, status, error) {
alert("There was a problem saving the report.");
});
});
This is the C# code that writes the file to disk:
try
{
string filePath = Globals.ReportsPath + OrganisationId + Path.DirectorySeparatorChar + AssessmentId + ".docx";
using Stream document = Syncfusion.EJ2.DocumentEditor.WordDocument.Save(Report, Syncfusion.EJ2.DocumentEditor.FormatType.Docx);
using FileStream file = new(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
await document.CopyToAsync(file).ConfigureAwait(false);
return true;
}
catch (Exception e)
{
Log.Error($"{GetType().Name}.{nameof(SaveReportAsync)}: {e.Message}");
return false;
}
Any ideas?
Thanks.
Hi Jon,
Currently we are checking this scenario and will update the details on August 13, 2024.
Regards,
Dhanush S
Thanks for taking a look.
In the meantime, I have found that this does work properly if I convert the .sfdt string to a DocIO WordDocument object first, and save it that way. eg.
string filePath = Globals.ReportsPath + OrganisationId + Path.DirectorySeparatorChar + AssessmentId + ".docx";
using Syncfusion.DocIO.DLS.WordDocument docIODocument = Syncfusion.EJ2.DocumentEditor.WordDocument.Save(Report);
using FileStream outputStream = new(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
docIODocument.Save(outputStream, Syncfusion.DocIO.FormatType.Docx);
I don't know if there's much overhead converting it this way, but it does allow me to overwrite any existing file without corrupting it.
Hi Jon,
The issue of file corruption when overwriting an existing file in your code is likely due to the use of FileMode.OpenOrCreate in the FileStream constructor. This mode opens the file if it exists, or creates a new file if it doesn't. However, when you open an existing file with this mode and overwrite it, the new content may not completely overwrite the old content, especially if the new content is smaller than the original file. This can leave leftover data from the original file, leading to corruption.
To ensure that the file is correctly overwritten, you should use FileMode.Create instead of FileMode.OpenOrCreate. FileMode.Create will always create a new file. If the file already exists, it will be overwritten and truncated to zero length before writing the new content. This ensures that there is no leftover data from the original file.
Code :
public async Task<bool> Export([FromBody] CustomParameter param) { try { string path = this.hostEnvironment.ContentRootPath + "\\Files\\" + param.fileName; using Stream document = Syncfusion.EJ2.DocumentEditor.WordDocument.Save(param.documentData, Syncfusion.EJ2.DocumentEditor.FormatType.Docx); // Use FileMode.Create to ensure the file is properly overwritten using FileStream file = new(path, FileMode.Create, FileAccess.Write); await document.CopyToAsync(file).ConfigureAwait(false); return true; } catch (Exception e) { // Handle exception, log it if necessary return false; } } |
Regards,
Dhanush S
Hi Dhanush,
This does indeed fix the problem. I didn't expect DocIO.DLS.WordDocument.Save and EJ2.DocumentEditor.WordDocument.Save to produce different results with the same FileMode setting, although I expect that's a limitation of writing to a file using a Stream for the source.
Thanks for your help!
Jon
Hi Jon,
We haven't experienced any issues on our end by switching the code from asynchronous to synchronous. Could you please clarify your requirements and let us know if you still wish to proceed with asynchronous coding?
Regards,
Dhanush S
Hi Dhanush,
I'm not quite sure what you mean. The suggestion you gave to use the "Create" mode when opening the FileStream solved my issue. I am able to use the CopyToAsync() method after that.
I was just pointing out that the DocIO.DLS.WordDocument behaves differently and does not corrupt files when using the "FileMode.OpenOrCreate" option to overwrite an existing file.
My issue is resolved so you can close this ticket.
Thanks once again,
Jon
Hi Jon,
Thank for your update
We are currently validating our process to ensure it produces the same results as the DocIO save API when saving with a stream. we will update the details on August 20, 2024.
Regards,
Dhanush S
Hi Jon,
Could you please confirm that whether you are facing issue after adding below highlighted code in your document exporting endpoint?
Regards,
Dhanush S
Hi Dhanush,
I didn't try SetLength(0), but since using the "Create" mode when opening the FileStream solved my issue, I'm happy to move on.
Regards,
Jon
Hi Jon,
Thanks for the update.
Please create a new ticket if you need any assistance. We would be happy to assist you as always.
Regards,
Dhanush S