Migrating From Piranha 7
If you've already create a new web project for .NET Core 3.0
or 3.1
you know that there are some differences between how these versions are configured in Startup.cs.
This of course also applies to Piranha, so let's take a look at what you need to do to upgrade your existing application.
Project File and References
When upgrading to netcoreapp3.1
one of the major differences is that all ASP.NET
references are now included as Framework References and nuget references ASP.NET
should be removed from your project. Let's take a look at the project file for the blog template as an example:
Piranha 7.1 for .NET Core 2.2
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
<PackageReference Include="Piranha" Version="7.1.0" />
<PackageReference Include="Piranha.AspNetCore" Version="7.1.0" />
<PackageReference Include="Piranha.AspNetCore.Identity.SQLite" Version="7.1.0" />
<PackageReference Include="Piranha.AttributeBuilder" Version="7.1.0" />
<PackageReference Include="Piranha.Data.EF" Version="7.1.0" />
<PackageReference Include="Piranha.ImageSharp" Version="7.1.0-rc1" />
<PackageReference Include="Piranha.Local.FileStorage" Version="7.1.0" />
<PackageReference Include="Piranha.Manager" Version="7.1.0" />
<PackageReference Include="Piranha.Manager.TinyMCE" Version="7.1.0" />
</ItemGroup>
</Project>
Piranha 8.0 for .NET Core 3.1
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.0" />
<PackageReference Include="Piranha" Version="8.0.0" />
<PackageReference Include="Piranha.AspNetCore" Version="8.0.0" />
<PackageReference Include="Piranha.AspNetCore.Identity.SQLite" Version="8.0.0" />
<PackageReference Include="Piranha.AttributeBuilder" Version="8.0.0" />
<PackageReference Include="Piranha.Data.EF" Version="8.0.0" />
<PackageReference Include="Piranha.ImageSharp" Version="8.0.0-rc1" />
<PackageReference Include="Piranha.Local.FileStorage" Version="8.0.0" />
<PackageReference Include="Piranha.Manager" Version="8.0.0" />
<PackageReference Include="Piranha.Manager.TinyMCE" Version="8.0.0" />
</ItemGroup>
</Project>
Configure Services
In ConfigureServices
the main difference is how the ASP.NET
services are added. AddMvc
has now been split into separate methods for Razor Pages and MVC.
Piranha 7.1 for .NET Core 2.2
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options =>
options.ResourcesPath = "Resources"
);
services.AddMvc()
.AddPiranhaManagerOptions()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddPiranha();
services.AddPiranhaApplication();
services.AddPiranhaFileStorage();
services.AddPiranhaImageSharp();
services.AddPiranhaManager();
services.AddPiranhaTinyMCE();
services.AddPiranhaMemoryCache();
services.AddPiranhaEF(options =>
options.UseSqlite(Configuration.GetConnectionString("piranha")));
services.AddPiranhaIdentityWithSeed<IdentitySQLiteDb>(options =>
options.UseSqlite(Configuration.GetConnectionString("piranha")));
}
Piranha 8.0 for .NET Core 3.0
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(options =>
options.ResourcesPath = "Resources"
);
services.AddControllersWithViews();
services.AddRazorPages()
.AddPiranhaManagerOptions();
services.AddPiranha();
services.AddPiranhaApplication();
services.AddPiranhaFileStorage();
services.AddPiranhaImageSharp();
services.AddPiranhaManager();
services.AddPiranhaTinyMCE();
services.AddPiranhaMemoryCache();
services.AddPiranhaEF(options =>
options.UseSqlite(Configuration.GetConnectionString("piranha")));
services.AddPiranhaIdentityWithSeed<IdentitySQLiteDb>(options =>
options.UseSqlite(Configuration.GetConnectionString("piranha")));
}
Configure
Again UseMvc
has been split up into a number of components that needs to be registered differenctly. Pay attention to the order of the middleware, and especially to the position of the Authorization and Authentication components.
Piranha 7.1 for .NET Core 2.2
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApi api)
{
// Initialize Piranha
App.Init(api);
// Configure cache level
App.CacheLevel = Piranha.Cache.CacheLevel.Basic;
// Build content types
var pageTypeBuilder = new Piranha.AttributeBuilder.PageTypeBuilder(api)
.AddType(typeof(Models.BlogArchive))
.AddType(typeof(Models.StandardPage));
pageTypeBuilder.Build()
.DeleteOrphans();
var postTypeBuilder = new Piranha.AttributeBuilder.PostTypeBuilder(api)
.AddType(typeof(Models.BlogPost));
postTypeBuilder.Build()
.DeleteOrphans();
// Configure Tiny MCE
EditorConfig.FromFile("editorconfig.json");
// Register middleware
app.UseStaticFiles();
app.UseAuthentication();
app.UsePiranha();
app.UsePiranhaManager();
app.UsePiranhaTinyMCE();
app.UseMvc(routes =>
{
routes.MapRoute(name: "areaRoute",
template: "{area:exists}/{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" });
routes.MapRoute(
name: "default",
template: "{controller=home}/{action=index}/{id?}");
});
}
Piranha 8.0 for .NET Core 3.1
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApi api)
{
// Initialize Piranha
App.Init(api);
// Configure cache level
App.CacheLevel = Piranha.Cache.CacheLevel.Basic;
// Build content types
var pageTypeBuilder = new Piranha.AttributeBuilder.PageTypeBuilder(api)
.AddType(typeof(Models.BlogArchive))
.AddType(typeof(Models.StandardPage));
pageTypeBuilder.Build()
.DeleteOrphans();
var postTypeBuilder = new Piranha.AttributeBuilder.PostTypeBuilder(api)
.AddType(typeof(Models.BlogPost));
postTypeBuilder.Build()
.DeleteOrphans();
// Configure Tiny MCE
EditorConfig.FromFile("editorconfig.json");
// Register middleware
app.UseStaticFiles();
app.UsePiranha();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UsePiranhaIdentity();
app.UsePiranhaManager();
app.UsePiranhaTinyMCE();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapPiranhaManager();
});
}
Introducing Simple Setup
To help migration to this version, and future version we've decided a more simple way to setup Piranha if you're building an integrated web application (i.e. a traditional application with a server-generated client). This setup method abstracts the gritty details of setting up the application and does this for you. Let's again take a look at how setup for the Blog template would look like.
ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddPiranha(options =>
{
options.UseFileStorage();
options.UseImageSharp();
options.UseManager();
options.UseTinyMCE();
options.UseMemoryCache();
options.UseEF(db =>
db.UseSqlite(Configuration.GetConnectionString("piranha")));
options.UseIdentityWithSeed<IdentitySQLiteDb>(db =>
db.UseSqlite(Configuration.GetConnectionString("piranha")));
});
}
Configure
Besides packaging all of the ASP.NET
setup we've also added a new ContentTypeBuilder
that adds all Content Types in the specified Assemblies for you. You can even add multiple assemblies by add several calls to AddAssembl
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApi api)
{
// Initialize Piranha
App.Init(api);
// Configure cache level
App.CacheLevel = Piranha.Cache.CacheLevel.Basic;
// Build content types
new ContentTypeBuilder(api)
.AddAssembly(typeof(Startup).Assembly)
.Build()
.DeleteOrphans();
// Configure Tiny MCE
EditorConfig.FromFile("editorconfig.json");
// Middleware setup
app.UsePiranha(options =>
{
options.UseManager();
options.UseTinyMCE();
options.UseIdentity();
});
}
Integrated Middleware
We've also added a new Integrated Middleware component that is enabled when using Simple Setup. This middleware component replaces all of the existing Piranha middleware components and processes the entire request in one pass. The result is better performance and more failsafe routing behavior for the application.
This new middleware can be used without Simple Setup as well by replacing the following line:
Standard Pipeline
app.UsePiranha();
Integrated Pipeline
app.UseIntegratedPiranha
Archive Pages
In our constant efforts to simplify things we will gradually remove the type ArchivePage<T>
which has been marked as obsolete from this version. Archive Pages should now inherit from the same base class as regular pages and is instead marked as Archives with the PageTypeAttribute
.
If you want a PostArchive Property on your Page just like before you add this manually, for example.
Archive Page in 7.1
[PageType(Title = "Blog archive", UseBlocks = false)]
public class BlogArchive : ArchivePage<BlogArchive>
{
}
Archive Page in 8.0
[PageType(Title = "Blog archive", UseBlocks = false, IsArchive = true)]
public class BlogArchive : Page<BlogArchive>
{
public PostArchive<DynamicPost> Archive { get; set; }
}
The reason for this is simply that the Archive is not populated when getting the Page model, and we want to give you the flexibility on how you handle your data model.