Word (RTF) Document Protection

The Word Processing Document API allows you to restrict document modification. Specify the protection type, password, and click Download. You can export the result to DOCX, DOC, or RTF format.

Options
Protection Type
Password (optional)
File Format
@model AspNetCoreDemos.OfficeFileAPI.WordRTFDocumentProtectionModel
@using DevExtreme.AspNet.Mvc

@{ Html.BeginForm("WordRTFDocumentProtectionExportTo", "DocumentProtection", FormMethod.Post); }

<div class="demo-view-container">
    @await Html.PartialAsync("WordRTFPreviewPartial", Model.PreviewModel)
</div>

<div class="options">
    <div class="caption">Options</div>
    <div class="option">
        <div class="label">Protection Type</div>
        @(Html.DevExtreme().SelectBoxFor(m => m.ProtectionType)
                           .DataSource(new List<SelectListItem>
                                    {   new SelectListItem{ Text="ReadOnly", Value = "1" },
                                        new SelectListItem{ Text="AllowComments", Value = "2" } }
                           .Select(i => new { Value = int.Parse(i.Value), Text = i.Text }))
                           .ValueExpr("Value")
                           .DisplayExpr("Text")
        )
    </div>
    <div class="option">
        <div class="label">Password (optional)</div>
        @(Html.DevExtreme().TextBoxFor(m => m.Password)
                           .Mode(TextBoxMode.Password)
        )
    </div>
    <div class="option">
        <div class="label">File Format</div>
        @(Html.DevExtreme().SelectBoxFor(m => m.FileFormat)
                           .DataSource(Html.GetEnumSelectList<AspNetCoreDemos.OfficeFileAPI.RichEditProtectionFileFormat>()
                           .Select(i => new { Value = int.Parse(i.Value), Text = i.Text }))
                           .ValueExpr("Value")
                           .DisplayExpr("Text")
        )
    </div>
    <div class="option-buttons">
        @(Html.DevExtreme().Button()
                           .Text("Download")
                           .Type(ButtonType.Default)
                           .StylingMode(ButtonStylingMode.Contained)
                           .UseSubmitBehavior(true)
        )
    </div>
</div>
@{ Html.EndForm(); }
@model AspNetCoreDemos.OfficeFileAPI.WordRTFPreviewModel

<iframe id="previewFrame" src="@Url.Action(Model.PreviewDocumentAction, Model.ControllerName)" height="@Model.IFrameSize" class="demo-preview-border" style="width:100%;box-sizing:border-box"></iframe>

<script type="text/javascript">
    WordRTFPreview = {
        basePath: '@Url.Action(Model.PreviewDocumentAction, Model.ControllerName)',
        Update: function (param) {
            var iframeElementName = "previewFrame";
            var iframeElement = document.getElementById(iframeElementName);
            if (!iframeElement)
                return;
            var additionalParams = "&" + new Date().valueOf();
            if (param)
                additionalParams = param;
            iframeElement.src = this.basePath + "?" + additionalParams;
        }
    };
</script>
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;

namespace AspNetCoreDemos.OfficeFileAPI {
    public partial class DocumentProtectionController : OfficeDemoController {
        public DocumentProtectionController(ILogger<DocumentProtectionController> logger, IWebHostEnvironment hostingEnvironment)
            : base(logger, hostingEnvironment) {
        }
        protected const string TsaServerUriInvalidExceptionString = "ERROR: TSA server URI is invalid or server doesn't support SHA-256 hashing algorithm";
    }
}
using System;
using System.IO;
using DevExpress.Office.Services;
using DevExpress.Web.Office;
using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;
using Microsoft.AspNetCore.Mvc;

namespace AspNetCoreDemos.OfficeFileAPI {
    public partial class DocumentProtectionController {
        const string wordRTFDocumentProtectionDefaultFile = "/Documents/DocumentForProtection.docx";
        public IActionResult WordRTFDocumentProtection() {
            WordRTFDocumentProtectionModel model = new WordRTFDocumentProtectionModel();
            return View(model);
        }

        public IActionResult WordRTFDocumentProtectionPreview(WordRTFDocumentProtectionModel model) {
            Stream stream = CreateDocumentStream(wordRTFDocumentProtectionDefaultFile, DocumentFormat.Html, (documentServer) => {
                documentServer.Document.Protect(model.Password, (DocumentProtectionType)model.ProtectionType);
            });
            return CreatePreviewResult(stream);
        }

        public IActionResult WordRTFDocumentProtectionExportTo(WordRTFDocumentProtectionModel model) {
            RichEditFileFormat fileFormat = model.FileFormat;
            DocumentFormat format = WordRTFUtils.ConvertToFormat(fileFormat);
            Stream stream = CreateDocumentStream(wordRTFDocumentProtectionDefaultFile, format, (documentServer) => {
                documentServer.Document.Protect(model.Password, (DocumentProtectionType)model.ProtectionType);
            });
            if(stream == null)
                return new EmptyResult();
            string contentType = WordRTFUtils.ConvertToContentType(fileFormat);
            string fileExtension = WordRTFUtils.ConvertToFileExtension(fileFormat);
            return CreateFileStreamResult(stream, contentType, fileExtension);
        }

        Stream CreateDocumentStream(string fileName, DocumentFormat documentFormat, Action<RichEditDocumentServer> protectionAction) {
            if(documentFormat == DocumentFormat.Undefined)
                return null;
            RichEditDocumentServer documentServer = CreateDocumentServer();
            string filePath = HostingEnvironment.ContentRootPath + fileName;
            documentServer.LoadDocument(filePath);
            protectionAction(documentServer);
            
            MemoryStream result = new MemoryStream();
            documentServer.SaveDocument(result, documentFormat);
            result.Seek(0, SeekOrigin.Begin);
            return result;
        }

        RichEditDocumentServer CreateDocumentServer() {
            RichEditDocumentServer documentServer = new RichEditDocumentServer();
            documentServer.Options.Export.Html.EmbedImages = true;
            return documentServer;
        }
    }
}
namespace AspNetCoreDemos.OfficeFileAPI {
    public class WordRTFDocumentProtectionModel : WordRTFModelBase {
        public WordRTFDocumentProtectionModel() {
            PreviewModel.PreviewDocumentAction = "WordRTFDocumentProtectionPreview";
            PreviewModel.ControllerName = "DocumentProtection";
            FileFormat = RichEditFileFormat.Docx;
            ProtectionType = 1;
        }

        public int ProtectionType { get; set; }
        public string Password { get; set; }
    }
}
namespace AspNetCoreDemos.OfficeFileAPI {
    public class WordRTFModelBase {
        public WordRTFModelBase() {
            PreviewModel = new WordRTFPreviewModel();
            PreviewModel.OwnerPropertyName = "PreviewModel";
            FileFormat = RichEditFileFormat.Rtf;
        }

        public RichEditFileFormat FileFormat { get; set; }
        public WordRTFPreviewModel PreviewModel { get; internal set; }
    }

    public class WordRTFPreviewModel {
        public WordRTFPreviewModel() {
        }

        public string OwnerPropertyName { get; set; }
        public string PreviewDocumentAction { get; set; }
        public string ControllerName { get; set; }
        public int IFrameSize { get; set; } = 452;
    }
}