Upgrading from v5.0.20 to v5.0.26

Who should apply these changes?

If you created your project from a StartSharp / Serene 5.0.26.0+ template you don't need to apply changes in this document.

If the project was created from 5.0.19 or an earlier version, then please first apply migrations earlier migrations listed on left.

StartSharp customers should use stargen to automate most of the changes listed here.

If you are not sure which version of a template your project was created from, you may check your sergen.json file. Since version 5.0.19, StartSharp/Serene projects contain information about the initial version of the template under UpgradeInfo section:

"UpgradeInfo": {
    "InitialType": "Premium",
    "InitialVersion": "5.0.20.0"
  }
>

If InitialVersion is not shown there, it means your initial template version is less than 5.0.19.

Serenity Package Versions

You should first update your Serenity package versions to 5.0.26 minimum.

Fixing JSDPF paths in PdfExportHelper

You should update the path for jspdf scripts in your PdfExportHelper.ts as it is moved to Serenity.Assets package as a static web assets:

from

"~/Scripts/jspdf.min.js"
"~/Scripts/jspdf.plugin.autotable.min.js"

to

"~/Serenity.Assets/Scripts/jspdf.min.js"
"~/Serenity.Assets/Scripts/jspdf.plugin.autotable.min.js"

Enabling DataProtection System

DataProtection allows the developer to configure default cryptographic algorithms, key storage locations, and the mechanism by which keys are protected at rest.

To enable, add these lines to your Startup.cs before services.AddAntiforgery.

If DataProtectionKeysFolder configuration is set in appsettings.json, application will store the keys in that folder.

This will let authentication cookies to stay valid between application restarts.

For more information check Configure ASP.NET Core Data Protection documentation.

public void ConfigureServices(IServiceCollection services)
{
    //...
    var dataProtectionKeysFolder = Configuration?["DataProtectionKeysFolder"];
    if (!string.IsNullOrEmpty(dataProtectionKeysFolder))
    {
        dataProtectionKeysFolder = Path.Combine(HostEnvironment.ContentRootPath, dataProtectionKeysFolder);
        if (Directory.Exists(dataProtectionKeysFolder))
            services.AddDataProtection()
                .PersistKeysToFileSystem(new DirectoryInfo(dataProtectionKeysFolder));
    }
    ///...

Add IExceptionLogger to FileController

To enable exception logging when something goes wrong during file uploads, add IExceptionLogger to your FileController through dependency injection:

using Serenity.Abstractions;

//...

public class FileController : Controller
{
    public FileController(IUploadStorage uploadStorage, ITextLocalizer localizer,
        IExceptionLogger logger = null) // add this param
    {
        UploadStorage = uploadStorage ??
            throw new ArgumentNullException(nameof(uploadStorage));
        Localizer = localizer ??
            throw new ArgumentNullException(nameof(localizer));
        Logger = logger; // add this line
    }

    protected IUploadStorage UploadStorage { get; }
    protected ITextLocalizer Localizer { get; }
    protected IExceptionLogger Logger { get; } // add this property

Then add Logger to UploadProcessor constructor as parameter.

[Route("File/HandleUploadRequest")]
private ServiceResponse HandleUploadRequest(HttpContext context)
{
    ...
    var processor = new UploadProcessor(UploadStorage, Logger)
    {
        ThumbWidth = 128,
        ThumbHeight = 96
    };

Fixing wkhtmltopdf path for ReportController

wkhtmltopdf is the tool that Serenity uses to generate PDF reports from HTML. To ensure correct path is used (next to YourApplication.Web.dll) and show a informative error message when executable not found, change your code in ReportController.cs from:

private byte[] RenderAsPdf(IReport report, string key, string opt)
{
...
    var converter = new HtmlToPdfConverter();

    var wkhtmlPath = System.IO.Path.Combine(typeof(ReportController).Assembly.Location, "wkhtmltopdf.exe");
    if (!System.IO.File.Exists(wkhtmlPath)) // linux?
        wkhtmlPath = System.IO.Path.Combine(typeof(ReportController).Assembly.Location, "wkhtmltopdf");

    if (System.IO.File.Exists(wkhtmlPath))
        converter.UtilityExePath = wkhtmlPath;

to

private byte[] RenderAsPdf(IReport report, string key, string opt)
{
...
    var converter = new HtmlToPdfConverter();

    var assemblyPath = System.IO.Path.GetDirectoryName(typeof(ReportController).Assembly.Location);

    var wkhtmlPath = System.IO.Path.Combine(assemblyPath, "wkhtmltopdf.exe");
    if (!System.IO.File.Exists(wkhtmlPath)) // linux?
        wkhtmlPath = System.IO.Path.Combine(assemblyPath, "wkhtmltopdf");

    if (System.IO.File.Exists(wkhtmlPath))
        converter.UtilityExePath = wkhtmlPath;
    else
        throw new ValidationError("Can't locate wkhtmltopdf.exe (or wkhtmltopdf in Linux) " +
            "that is required for report generation at folder " + assemblyPath +
            ". Please download the version suitable for your system from " +
            "https://wkhtmltopdf.org/downloads.html");

Update Project to Call dotnet sergen restore on Build

Whenever you update a Serenity package, you should run dotnet sergen restore to update static content like scripts, css, typings etc. in your project.

As this can be forgotten to run manually, lets add this line to your project file to automate it on build:

<Target Name="TransformMvcClientTypes" BeforeTargets="BeforeBuild">
  <Exec Command="dotnet tool restore" ContinueOnError="true" />
  <Exec Command="$(DotNetSergen) restore" ContinueOnError="true" /> <!--add this-->
  <Exec Command="$(DotNetSergen) mvct" ContinueOnError="true" />
</Target>
...