Skip to main content
All docs
V24.1

Amazon ECS (Linux Container) Using AWS Fargate - Office File API Web App Deployment

  • 6 minutes to read

This topic uses the Microsoft Visual Studio UI to create, dockerize, and deploy a sample Web API application that uses the Office File API library. The application merges uploaded documents, adds a barcode, and creates a PDF file.

The application is deployed to Amazon ECS (Linux containers) using AWS Fargate.

Amazon ECS with AWS Fargate is a fully managed container service that deploys Linux container images.

In this example, the ASP.NET Core application is deployed to Amazon ECS using an existing Dockerfile from the Microsoft Visual Studio UI. This method publishes the application as a container image on Linux.

Prerequisites

  1. Active AWS IAM Credentials.
  2. Visual Studio 2022 with the ASP.NET and web development workload.
  3. AWS Toolkit for Visual Studio.
  4. Node.js (LTS version).
  5. The latest version of Docker desktop. You can find more information about Docker in the following topic: Get Docker.
  6. Your personal DevExpress NuGet credentials. Refer to the following help topic for instructions on how to obtain the feed URL and authorization key: Choose Between Offline and Online DevExpress NuGet Feeds.

Office File API Linux Support

For more information on Office File API on Linux, review the following help topics:

Create an ASP.NET Core Web API Application

  • From the File menu, select New > Project.
  • Enter Web API in the search box.
  • Select the ASP.NET Core Web API template and click Next.
  • In the Configure your new project dialog, name the project DXOfficeAwsDockerSample and click Next.
  • In the Additional information dialog, specify the .NET version, enable Docker, specify the Docker OS (Linux), enable OpenAPI support, and ensure that the checkbox for Use controllers is selected:

    Additional information Dialog

  • Click Create.

Always Generate Swagger Definitions

To ensure that Swagger definitions are always present in Azure API Management, they must be generated independently of the application environment. To generate these definitions, comment out the conditional block:

//if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
//}

Install DevExpress NuGet Packages

Visit nuget.devexpress.com, log in to your account, and click Obtain Feed URL. Open the NuGet Package Manager in Visual Studio and register the DevExpress NuGet feed as the package source. Install the following packages:

DevExpress.Document.Processor
This package includes the Word Processing Document API and other Office File API libraries. You need a license for the DevExpress Office File API Subscription or the DevExpress Universal Subscription to use this package in production code.
DevExpress.Drawing.Skia
This package implements the cross-platform PDF renderer based on the Skia Graphics Library. For more information, review the following help topic: DevExpress.Drawing Graphics Library.

If you are new to NuGet packages, see the following installation guide for assistance: Install DevExpress Packages Using NuGet Package Manager.

Implement Web API Controller

Add a new SampleController.cs class file to the Controllers folder. Override its contents with the following code snippet:

using DevExpress.BarCodes;
using DevExpress.Drawing;
using DevExpress.Office.Services;
using DevExpress.XtraRichEdit.API.Native;
using DevExpress.XtraRichEdit;
using Microsoft.AspNetCore.Mvc;
using System.Drawing;
using System.Text;
using DevExpress.XtraSpreadsheet.Services;

namespace DXOfficeAwsDockerSample.Controllers {
    [ApiController]
    [Route("[controller]")]
    public class SampleController : ControllerBase {
        [HttpPost]
        public async Task<IActionResult> Get(IFormFile[] files) {
            try {
                OfficeCharts.Instance.ActivateCrossPlatformCharts(); // enable chart support
                using (var server = new RichEditDocumentServer()) {
                    await MergeDocuments(server, files);
                    server.Document.AppendSection();
                    Stream imageStream = GenerateBarCode();
                    server.Document.Images.Append(DocumentImageSource.FromStream(imageStream));

                    MemoryStream resultStream = new MemoryStream();
                    server.ExportToPdf(resultStream);
                    resultStream.Seek(0, SeekOrigin.Begin);
                    return File(resultStream, "application/pdf", "result.pdf");
                }
            }
            catch (Exception e) {
                return StatusCode(500, e.Message + Environment.NewLine + e.StackTrace);
            }
        }

        async Task MergeDocuments(RichEditDocumentServer server, IFormFile[] files) {
            using (var stream = new MemoryStream()) {
                await files[0].CopyToAsync(stream);
                stream.Seek(0, SeekOrigin.Begin);
                server.LoadDocument(stream);
            }
            for (int i = 1; i < files.Length; i++) {
                using (var stream = new MemoryStream()) {
                    await files[i].CopyToAsync(stream);
                    stream.Seek(0, SeekOrigin.Begin);
                    server.Document.AppendDocumentContent(stream);
                }
            }
        }

        Stream GenerateBarCode() {
            // Create a QR code.
            BarCode barCode = new BarCode();
            barCode.Symbology = Symbology.QRCode;
            barCode.CodeText = "https://www.devexpress.com";
            barCode.BackColor = Color.White;
            barCode.ForeColor = Color.Black;
            barCode.RotationAngle = 0;
            barCode.CodeBinaryData = Encoding.Default.GetBytes(barCode.CodeText);
            barCode.Options.QRCode.CompactionMode = QRCodeCompactionMode.Byte;
            barCode.Options.QRCode.ErrorLevel = QRCodeErrorLevel.Q;
            barCode.Options.QRCode.ShowCodeText = false;
            barCode.DpiX = 72;
            barCode.DpiY = 72;
            barCode.Module = 2f;

            // Save the barcode as an image.
            var stream = new MemoryStream();
            barCode.Save(stream, DXImageFormat.Png);
            return stream;
        }
    }
}

Open the DXOfficeAwsDockerSample.http file in the editor and replace the weatherforecast route with the sample route to the newly created controller:

// ...
GET {{DXOfficeAwsDockerSample_HostAddress}}/sample/
// ...

Delete the WeatherForecastController.cs and WeatherForecast.cs files as they are no longer needed.

Add a Secret File

The secrets.dev.yaml file is used to manage sensitive information securely within a development environment. It helps developers work with sensitive data while minimizing security risks.

Add the secrets.dev.yaml file to the project’s root. Copy the personal NuGet feed URL to the file:

https://nuget.devexpress.com/{your-feed-authorization-key}/api

Add Dockerfile Build Arguments to the Project File

To use a secret, modify the Docker build command line. To do this, select Edit Project File to open the DXOfficeAwsDockerSample.csproj file in the editor, and add the following statement to the PropertyGroup section:

<DockerfileBuildArguments>--secret id=dxnuget,source=secrets.dev.yaml</DockerfileBuildArguments>

Modify the Dockerfile

The Dockerfile in your project folder contains instructions required to build a Docker image and deploy it inside a container. Add the following commands to your Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base

WORKDIR /app
EXPOSE 8080

# DX
# Install the latest version of font libraries
RUN apt update &&\
         apt install -y libc6 libicu-dev libfontconfig1

# (Optional step) Install the ttf-mscorefonts-installer package
# to use Microsoft TrueType core fonts in the application
RUN echo "deb http://ftp.debian.org/debian/ bullseye contrib" >> /etc/apt/sources.list
RUN apt update
RUN apt install -y ttf-mscorefonts-installer 
# /DX

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src

# DX
# Specify your DevExpress NuGet Feed URL as the package source
RUN --mount=type=secret,id=dxnuget dotnet nuget add source $(cat /run/secrets/dxnuget) -n devexpress-nuget
# /DX

COPY ["DXOfficeAwsDockerSample.csproj", "DXOfficeAwsDockerSample/"]
RUN dotnet restore "DXOfficeAwsDockerSample/DXOfficeAwsDockerSample.csproj"
COPY ["./", "DXOfficeAwsDockerSample/"]
WORKDIR "/src/DXOfficeAwsDockerSample"
RUN dotnet build "DXOfficeAwsDockerSample.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "DXOfficeAwsDockerSample.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "DXOfficeAwsDockerSample.dll"]

Set Up a Publishing Profile for AWS Fargate

  1. In Visual Studio, open the AWS Explorer window, and log in to the AWS account.
  2. Right-click the project name in the Solution Explorer window and select Publish to AWS:

    Publish to AWS Menu

  3. In the Publish to AWS window, select the ASP.NET Core App to Amazon ECS using AWS Fargate option:

    Select Publish Fargate Option

  4. Click Edit settings and specify the Project Build options as follows:

    Option Value
    Docker Build Args –secret id=dxnuget,source=secrets.dev.yaml
    Docker Execution Directory .

    Docker Options

Publish the Application

  1. Click Publish to start deployment. Note that initial publishing takes longer because it creates a new ECS service. The Publish to AWS action adds a Dockerfile to the project, creates a container, uploads it to Amazon ECR, creates a task definition, and creates an ECS cluster with a default service and task for your container.

  2. Publishing is complete when a green check mark appears at the top and the output of the publishing log stops.

  3. The URL displayed with the Endpoint label in the panel on the right can be used to access the application after it has been successfully published.