Upload word document to .Net core WebAPI

We’ll be working with a .docm template in Word 2016 which contains a textbox. This control is given a name using the Content Control Properties.

This is available under Developer Menu in MS Word, then click on Properties.

Save this template as .docm

Create .Net Core WebAPI under .net core version 3.1 for this example. The sample code is as below. The library System.IO is used to access the value in the variable.

using System;
using System.IO;
using System.IO.Packaging;
using System.Xml;
using System.Xml.XPath;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace SampleApplicationUpload.Controllers
{
    public class UploadController : ControllerBase
    {
        [HttpPost]
        [Route("upload")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public IActionResult Upload()
        {
            string filename = string.Empty;
            string extension = string.Empty;
            string result = string.Empty;
            bool uploaded = false;
            string ModifiedBy = string.Empty;
            var request = HttpContext.Request;

            if (request.Form.Files.Count > 0)
            {
                filename = request.Form.Files[0].FileName;
                extension = filename.Substring(filename.LastIndexOf(".")).ToLower();
                if (!string.IsNullOrEmpty(extension) && extension.Equals(".docm"))
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        request.Form.Files[0].CopyTo(memoryStream);
                        if (memoryStream.Length < 2097152)
                        {
                            result = UploadWorStream(memoryStream, extension, out ModifiedBy, out uploaded);
                        }
                        else
                        {
                            return BadRequest("File size too large");
                        }
                    }
                }
                else
                {
                    return BadRequest("File format not recognised. Upload .docm file only");
                }
            }           
            return Ok(result);
        }
        private string UploadWorStream(MemoryStream ms, string ext, out string ModifiedBy, out bool uploaded)
        {
            string contenttype = string.Empty;
            bool erroroccurs = false;
            ModifiedBy = string.Empty;
            var xmlDoc = new XmlDocument();
            uploaded = false;
            switch (ext)
            {
                case ".docm":
                    contenttype = "application/vnd.ms-word";
                    break;
                default:
                    erroroccurs = true;
                    break;
            }

            if (!erroroccurs)
            {
                if (contenttype != string.Empty)
                {
                    Stream fs = ms;
                    var br = new BinaryReader(fs);
                    string xmlDocRelType = "http://schemas.openxmlformats.org/officeDocument/" +
                                           "2006/relationships/customXml";
                    string officeDocRelType = "http://schemas.openxmlformats.org/" +
                                              "officeDocument/2006/relationships/officeDocument";
                    PackagePart xmlPart = default(PackagePart);
                    PackagePart documentPart = default(PackagePart);
                    Uri documentUri = default(Uri);
                    Uri xmlUri = default(Uri);
                    using (Package officePackage = Package.Open(fs, FileMode.Open, FileAccess.Read))
                    {
                        foreach (var relationship1 in officePackage.GetRelationshipsByType(officeDocRelType))
                        {
                            documentUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
                                                                       relationship1.TargetUri);
                            documentPart = officePackage.GetPart(documentUri);
                            break;
                        }

                        if (documentPart != null)
                            foreach (var relationship2 in documentPart.GetRelationshipsByType(xmlDocRelType))
                            {
                                xmlUri = PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative),
                                                                      relationship2.TargetUri);
                            }
                        xmlPart = officePackage.GetPart(xmlUri);
                        Stream inputStream = xmlPart.GetStream(FileMode.Open, FileAccess.Read);
                        var ts = new StreamReader(inputStream);
                        xmlDoc.Load(ts);
                        ts.Close();
                        ts.Dispose();
                        officePackage.Close();
                    }

                    XPathNavigator xpnGet2 = xmlDoc.CreateNavigator();
                   // string txtSample = xpnGet2.Evaluate("string(//ROOT[1]/SampleDoc[1]/@txtSample)").ToString();
                    string txtSample = Convert.ToString(xpnGet2.Evaluate("string(//ROOT/SampleDoc/@txtSample)"));
                    if (txtSample.Length > 0)
                    {
                        return txtSample;
                    }
                    else {
                        return "Unable to read document";
                    }
                }
                else
                {
                    uploaded = false;
                    return "Error";
                }
            }
            else
            {
                uploaded = false;
                return "Error";
            }
        }
    }
}

Finally try to access the WebAPI using a Postman request and check the value while debugging the end-point.

curl --location --request POST 'https://localhost:<port>/upload' \
--form 'attachment
=@/C:/Users/username/Desktop/TestDocument.docm'

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.