C# using ASP.NET
In this chapter, you'll integrate Oicana into a C# web service using ASP.NET Core. ASP.NET Core is Microsoft's modern, cross-platform framework for building web applications and APIs. We'll create a simple web service that compiles your Oicana template to PDF and serves it via an HTTP endpoint.
Note
This chapter assumes, that you have a working .NET 8 setup. If that is not the case, please follow the official Microsoft guide to install .NET on your machine.
Let's start with a fresh ASP.NET project by executing dotnet new webapidotnet new webapi in a new directory. The starter project has a single endpoint defined in Program.csProgram.cs. We can try that endpoint out in the swagger UI. Start up the service (dotnet rundotnet run) and follow the link printed in the terminal. If the page is empty, navigate to /swagger/swagger. In the swagger UI, expand the /weatherforecast/weatherforecast endpoint, press "Try it out", then "Execute". This will send an HTTP request to the running ASP.NET service and return made up weather data.
We will define a new endpoint to compile our Oicana template to a PDF and return the PDF file to the user.
- Create a new directory in the .NET project called
templatestemplatesand copyexample-0.1.0.zipexample-0.1.0.zipinto that directory. - Add the
OicanaOicanaNuGet package as a dependency withdotnet add package Oicana --prereleasedotnet add package Oicana --prerelease. -
Read the template file and prepare it for compilation at the beginning of
Program.csProgram.cs:Note
Template registration (the
new Template()new Template()call) compiles the template once in development mode to warm up the Typst cache. This happens at startup and uses thedevelopmentdevelopmentvalue of the input you defined previously. -
Replace the generated
/weatherforecast/weatherforecastendpoint with the following:This code defines a new POST endpoint at
/compile/compile. For every request, it compiles the template to PDF with two empty input lists and returns the file. We useCompilationMode.DevelopmentCompilationMode.Developmenthere to demonstrate how the template falls back to the development value you defined for theinfoinfoinput ("Chuck Norris"). In a later step we will explicitly set a value for the input.
After restarting the service and refreshing the swagger UI, you should see the new endpoint. Open up the endpoint description and click "Try it out" and "Execute" to send a request to the server. You should see a successful response with a download button for the PDF file.
The PDF generation should not take longer than a couple of milliseconds. You can look at the request duration in the network tab of your browser's debugging tools for an estimation. The first request to an APS.NET service can be significantly slower than later ones, because ASP.NET does some preparation during the first request.
For a better measurement of the compilation speed on your machine, you can use a StopwatchStopwatch in the endpoint code.
Now let's use the template with inputs that you defined in the previous chapter. First, make sure to update the packed template in your ASP.NET project. Run oicana packoicana pack in the template directory and replace example-0.1.0.zipexample-0.1.0.zip in the ASP.NET project with the new file.
Our compilecompile endpoint is currently calling template.Compile([], [], ExportOptions.Pdf(), new CompilationOptions(CompilationMode.Development))template.Compile([], [], ExportOptions.Pdf(), new CompilationOptions(CompilationMode.Development)). This compiles the template without any explicit inputs. The first empty array are the jsonjson inputs and the second one the blobblob inputs. Now we'll provide an input value and switch to production mode.
Change the endpoint to set the name input you defined earlier.
Notice that we switched to CompilationMode.ProductionCompilationMode.Production now that we're providing explicit input values. Production mode is the recommended default for all document compilation in your application - it ensures you never accidentally generate a document with test data. In production mode, the template will never fall back to development values. If an input value is missing in production mode and the input does not have a default value, the compilation will fail unless your template handles nonenone values for that input.
Calling the endpoint now, will result in a PDF with "Baby Yoda" instead of "Chuck Norris". Building on this minimal service, one could set input values based on database entries or the request payload. Take a look at the open source ASP.NET example project on GitHub for a more complete showcase of the Oicana C# integration.