Standard and Custom Saving

  • 5 min to read

This topics describes different save scenarios that you can implement for office controls.

Simple Save Scenario

In the simplest application scenario, office controls perform document save operations without custom coding. For instance, if an office control opens a document from the server's local file system (using the Open(pathToDocument) method), the document is then saved by the office control to the same file from which it was opened (based on the pathToDocument parameter of the Open method). In this case, click the Save ribbon command in the UI or call the Save() method of an office control to save the edited document to its original file.

Save Methods

More complex application scenarios might require additional coding and use more specific save methods. You can programmatically initialize document saving via the Save method and SaveCopy method overloads listed below.

Save Method

The Save method initiates a save operation for an office control's active document. In the simple scenario described above, this method successfully saves a document that was opened from the server file system, whose DocumentId equals the document's file path. If the edited document's DocumentId is not specified (e.g., if it is a new document or a document that was not opened from the server's file system), an office control will throw a specific exception. In this case, implement custom saving logic via the Saving event.

SaveCopy Method

You can use the SaveCopy method overloads to save a copy of an open document to the server file system or to an external storage. Specify the copy's destination by selecting the SaveCopy method overload with the necessary parameters. You can call this method for an active document in an office control (via the control's SaveCopy method) or for any open document currently maintained by DocumentManager (via the SaveCopy method of the IDocumentInfo identifying the document). In certain cases, the SaveCopy method may lead to multi-user conflicts, which arise when end-users try to save to and rewrite another document opened by other end-users. Implement custom saving logic using the Saving event to resolve this conflict.

Custom Saving - Using the Saving Event

A custom implementation is required when an office control does not have enough information to complete the document save operation automatically. Such situations occur when an office control tries to save a document that was opened from a custom document storage (such as a database) – and not from the server file system – via the following Open method overloads.

Open(string documentId, DocumentFormat format, Func<Stream> contentAccessor)

Open(string documentId, DocumentFormat format, Func<byte[]> contentAccessor)

Office controls expose the Saving server event, which enables you to handle document save operations in a custom manner. The event argument's e.DocumentID property (DocumentSavingEventArgs.DocumentID) identifies the document to be saved. Implement your custom saving logic and set the e.Handled property (DocumentSavingEventArgs.Handled) to true in the Saving event handler.

The example below shows how to save a document as a byte array:


public static class SaveHelper {
    public static void OnSaving(object source, DevExpress.Web.Office.DocumentSavingEventArgs e) {

        var spreadsheet = (ASPxSpreadsheet)source;

        // Get the document content to be saved as a byte array
        byte[] documentContentAsByteArray = spreadsheet.SaveCopy(DocumentFormat.Xlsx);
        SaveToCustomStorage(documentContentAsByteArray, e.DocumentID);

        e.Handled = true;
    }

    private static void SaveToCustomStorage(byte[] documentContent, string p) {
        // Your custom logic to save a document to custom storage
    }
}

The example below shows how to save a document as a stream:


public static class SaveHelper {
    public static void OnSaving(object source, DevExpress.Web.Office.DocumentSavingEventArgs e) {

        var spreadsheet = (ASPxSpreadsheet)source;

        // Get the document content to be saved as a stream
        using (MemoryStream documentContentAsStream = new MemoryStream()) {
            spreadsheet.SaveCopy(documentContentAsStream, DocumentFormat.Xlsx);
            SaveToCustomStorage(documentContentAsStream, e.DocumentID);
        }

        e.Handled = true;
    }

    private static void SaveToCustomStorage(MemoryStream ms, string p) {
        // Your custom logic to save a document to custom storage
    }
}

If a custom saving procedure is required, but is not provided (or e.Handled is not set to true), the save operation may try to proceed and finish with an exception.

NOTE

It is recommended that you declare the Saving event handler as a globally available static method. This handler can be used by the Auto-Saving feature if it is enabled for an office control.

See the following examples on how to save and load documents from a database to learn more.

Resolving Save Operation Conflicts

The Saving event can also be used to solve multi-user conflicts during save operations. These conflicts might arise when an end-user uses the SaveAs UI command (or the SaveCopy method overload is used in code) to save an office control's active document to another open document by overriding it. A conflict occurs when the target document is already opened by DocumentManager and contains unsaved changes made by another user.

The Save event's argument exposes the MultiUserConflict property (DocumentSavingEventArgs.MultiUserConflict), which informs you about a possible reason for the conflict. The property can have the following values:

You can resolve the issue by setting the MultiUserConflictResolve property (DocumentSavingEventArgs.MultiUserConflictResolve) to one of the following values.

  • MultiUserConflictResolve.Override

    Specifies that the target open document should be overridden with the currently processed document.

  • MultiUserConflictResolve.Persist

    Specifies that the target open document should be persisted. A specific exception will be thrown for the processed document: "It is impossible to save to an already opened file."

The example below illustrates how to prevent document override:


public static class SaveHelper {
    public static void OnSaving(object source, DevExpress.Web.Office.DocumentSavingEventArgs e) {
        if(e.MultiUserConflict == DevExpress.Web.Office.MultiUserConflict.OtherUserDocumentOverride)
            e.MultiUserConflictResolve = DevExpress.Web.Office.MultiUserConflictResolve.Persist;

        ...

        e.Handled = true;
    }
See Also