Headless CMS based on ASP.NET Core and Blazor
$ dotnet add package DragonFly.BlockField| Package | Release |
|---|---|
| DragonFly.Core | |
| DragonFly.AspNetCore | |
| DragonFly.API | |
| DragonFly.Client | |
| DragonFly.BlockField | |
| DragonFly.Generator | |
| DragonFly.ImageWizard | |
| DragonFly.MongoDB | |
| DragonFly.Identity | |
| DragonFly.ApiKeys |

To use the project template you need first to download and install it from NuGet.
dotnet new install DragonFly.Templates
After this you can create the project with:
dotnet new DragonFly
If you have a remote MongoDB instance, you need to add some appsettings:
"MongoDB": {
"Hostname": "localhost",
"Database": "DragonFly_App",
"Port": 27017,
"Username": "",
"Password": ""
},
IContentStorage contentStorage = ...;//use MongoStorage or ClientContentService (http client)
//create brand schema
ContentSchema schemaBrand = new ContentSchema("Brand")
.AddString("Name")
.AddSlug("Slug")
.AddTextArea("Description");
//Define schema for product
ContentSchema schemaProduct = new ContentSchema("Product")
.AddReference("Brand")
.AddString("Name", options => options.IsRequired = true)
.AddSlug("Slug")
.AddBool("IsAvailable", options => options.DefaultValue = true)
.AddFloat("Price")
.AddTextArea("Description", options => options.MaxLength = 255)
.AddArray("Attributes", options => options
.AddString("Name")
.AddString("Value"));
await contentStorage.CreateAsync(schemaProduct);
//create product by schema
ContentItem contentProduct = schemaProduct
.CreateContent()
.SetReference("Brand", new ContentItem(Guid.Parse(""), schemaBrand))
.SetString("Name", "ProductA")
.SetBool("IsAvailable", true)
.SetFloat("Price", 9.99)
.SetTextArea("Description", "...")
.AddArrayItem("Attributes", schemaProduct, item => item
.SetString("Name", "Size")
.SetString("Value", "M"));
await contentStorage.CreateAsync(contentProduct);
DragonFly.Generator
[ContentItem]
public partial class BlogPost
{
[DateField(Required = true)]
private DateTime? _date;
[StringField(Required = true, Searchable = true, ListField = true, MinLength = 8, MaxLength = 512)]
private string? _title;
[TextField]
private string? _description;
[SlugField(Required = true, Index = true)]
private string? _slug;
[AssetField(ListField = true, ShowPreview = true)]
private AssetField _image;
[BlockField]
private BlockField _mainContent;
}
builder.Services.AddDragonFly()
.AddModels(x => x.Add<BlogPost>());
//get all items
var result = await ContentStorage.QueryAsync<BlogPostModel>(x => x
.Published(true)
.Top(10)
.Slug(x => x.Slug, "my-product")
.Integer(x => x.Quantity, 10, NumberQueryType.Equal)
.String(x => x.Title, "Test", StringQueryType.Equal)
);
For long running jobs you can use the BackgroundTaskManager.
IBackgroundTaskManager taskManager = app.Services.GetRequiredService<IBackgroundTaskManager>();
taskManager.Start("Test", async ctx => await Task.Delay(TimeSpan.FromSeconds(60), ctx.CancellationToken));
builder.Services.Configure<DragonFlyOptions>(Configuration.GetSection("General"));
builder.Services.Configure<MongoDbOptions>(Configuration.GetSection("MongoDB"));
//add DragonFly services
builder.Services.AddDragonFly()
.AddImageWizard()
.AddRestApi()
.AddMongoDbStorage()
.AddMongoDbIdentity()
.AddBlockField()
.AddApiKeys();
var app = builder.Build();
//init DragonFly
await app.InitDragonFlyAsync();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebAssemblyDebugging();
}
app.UseDragonFly(x => x
.MapImageWizard()
.MapApiKey()
.MapIdentity()
.MapRestApi());
app.UseDragonFlyManager();
app.UseRouting();
app.Run();
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<DragonFly.App.Client.App>("app");
//Register DragonFly components
builder.AddDragonFly()
.AddRestApi()
.AddBlockField()
.AddIdentity()
.AddApiKeys();
WebAssemblyHost host = builder.Build();
await host.InitDragonFlyAsync();
await host.RunAsync();