added BlazorAppRadzenHtmlEditor
25
src/BlazorAppRadzenHtmlEditor/BlazorAppRadzenHtmlEditor.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34601.278
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorAppRadzenHtmlEditor", "BlazorAppRadzenHtmlEditor\BlazorAppRadzenHtmlEditor.csproj", "{F294D76E-112B-49BC-ACAD-06F83FD41D64}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F294D76E-112B-49BC-ACAD-06F83FD41D64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F294D76E-112B-49BC-ACAD-06F83FD41D64}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F294D76E-112B-49BC-ACAD-06F83FD41D64}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F294D76E-112B-49BC-ACAD-06F83FD41D64}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {33D655BE-FD9B-42AE-BDF3-CADB373E4149}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageReference Include="Radzen.Blazor" Version="4.31.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<base href="/" />
|
||||
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
|
||||
|
||||
<link rel="stylesheet" href="_content/Radzen.Blazor/css/standard-base.css">
|
||||
|
||||
@* <link rel="stylesheet" href="app.css" /> *@
|
||||
@* <link rel="stylesheet" href="BlazorAppRadzenHtmlEditor.styles.css" /> *@
|
||||
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<HeadOutlet @rendermode="InteractiveServer" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<Routes @rendermode="InteractiveServer" />
|
||||
|
||||
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
|
||||
<script src="_framework/blazor.web.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,65 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject DialogService DialogService
|
||||
@inject ContextMenuService ContextMenuService
|
||||
@inject TooltipService TooltipService
|
||||
@inject NotificationService NotificationService
|
||||
|
||||
<RadzenDialog />
|
||||
<RadzenNotification />
|
||||
<RadzenTooltip />
|
||||
<RadzenContextMenu />
|
||||
|
||||
|
||||
@* <RadzenComponents /> *@
|
||||
|
||||
|
||||
|
||||
<RadzenLayout style="grid-template-areas: 'rz-sidebar rz-header' 'rz-sidebar rz-body';">
|
||||
<RadzenHeader>
|
||||
<RadzenRow JustifyContent="JustifyContent.Start" AlignItems="AlignItems.Center" Gap="0">
|
||||
<RadzenColumn Size="5">
|
||||
<RadzenSidebarToggle Click="@SidebarToggleClick"></RadzenSidebarToggle>
|
||||
</RadzenColumn>
|
||||
<RadzenColumn Size="7">
|
||||
<RadzenStack AlignItems="AlignItems.Center" Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.End"></RadzenStack>
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
</RadzenHeader>
|
||||
<RadzenBody Expanded="@sidebarExpanded">
|
||||
<RadzenRow class="rz-mx-auto rz-px-4 rz-pt-2 rz-pt-md-4 rz-pt-lg-6 rz-pt-xl-12 rz-pb-2 rz-pb-lg-12" Style="max-width: 1440px;">
|
||||
<RadzenColumn Size="12">
|
||||
@Body
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
</RadzenBody>
|
||||
<RadzenSidebar Expanded="@sidebarExpanded" style="z-index: 2">
|
||||
<RadzenStack AlignItems="Radzen.AlignItems.Center" class="rz-py-4 rz-py-lg-6" Style="padding: var(--rz-panel-menu-item-padding); border-bottom: var(--rz-panel-menu-item-border);">
|
||||
|
||||
@* <RadzenImage Path="images/logo.png" style="width: 48px; height: 48px;"></RadzenImage>
|
||||
*@
|
||||
<RadzenText Text="appname" TextStyle="Radzen.Blazor.TextStyle.Subtitle1" class="rz-mb-0" style="color: var(--rz-sidebar-color);" />
|
||||
</RadzenStack>
|
||||
|
||||
<NavMenu />
|
||||
|
||||
<RadzenStack AlignItems="Radzen.AlignItems.Center" Gap="0" class="rz-py-4 rz-py-lg-6" Style="padding: var(--rz-panel-menu-item-padding);">
|
||||
<RadzenText Text="appname v1.0.0" TextStyle="Radzen.Blazor.TextStyle.Caption" style="color: var(--rz-text-disabled-color);" TagName="Radzen.Blazor.TagName.P" TextAlign="Radzen.TextAlign.Center" />
|
||||
<RadzenText Text="Copyright Ⓒ 2024" TextStyle="Radzen.Blazor.TextStyle.Caption" class="rz-mb-0" style="color: var(--rz-text-disabled-color);" TagName="Radzen.Blazor.TagName.P" TextAlign="Radzen.TextAlign.Center" />
|
||||
</RadzenStack>
|
||||
|
||||
</RadzenSidebar>
|
||||
</RadzenLayout>
|
||||
|
||||
|
||||
@code {
|
||||
bool sidebarExpanded = true;
|
||||
|
||||
void SidebarToggleClick()
|
||||
{
|
||||
sidebarExpanded = !sidebarExpanded;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
<RadzenPanelMenu>
|
||||
|
||||
<RadzenPanelMenuItem Text="Home" Path="/" />
|
||||
<RadzenPanelMenuItem Text="Posts" Path="/Posts" />
|
||||
<RadzenPanelMenuItem Text="Posts Panel" Path="/BlogPost" />
|
||||
|
||||
</RadzenPanelMenu>
|
||||
@@ -0,0 +1,102 @@
|
||||
@page "/BlogPost/Create"
|
||||
|
||||
<RadzenText Text="Create" TextStyle="TextStyle.H5" />
|
||||
|
||||
@if (blogPostViewModel == null)
|
||||
{
|
||||
<p>Loading...</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<RadzenStack>
|
||||
<RadzenFieldset Text="New Post">
|
||||
<RadzenStack Gap="2rem">
|
||||
<EditForm Context="editFormNewPost" Model="@blogPostViewModel" OnValidSubmit="HandleValidSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Title" for="title" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
<InputText id="title" class="form-control" placeholder="Title"
|
||||
@bind-Value="blogPostViewModel.Title" />
|
||||
<ValidationMessage For="@(() => blogPostViewModel.Title)" />
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Content" for="content" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
@*
|
||||
<InputText id="content" class="form-control" placeholder="Content"
|
||||
@bind-Value="blogPostViewModel.Content" />
|
||||
<ValidationMessage For="@(() => blogPostViewModel.Content)" />
|
||||
*@
|
||||
|
||||
<RadzenHtmlEditor @bind-Value=@blogPostViewModel.Content
|
||||
Input=@OnInput Change=@OnChange
|
||||
Paste=@OnPaste Execute=@OnExecute
|
||||
UploadUrl="upload/image" />
|
||||
<ValidationMessage For="@(() => blogPostViewModel.Content)" />
|
||||
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenButton Text="Save" Icon="save"
|
||||
ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Success" />
|
||||
|
||||
</EditForm>
|
||||
|
||||
</RadzenStack>
|
||||
</RadzenFieldset>
|
||||
</RadzenStack>
|
||||
|
||||
<RadzenButton Text="Back" Icon="arrow_back" Class="rz-mt-2"
|
||||
Click="NavigatetoBlogPostIndex"
|
||||
ButtonStyle="ButtonStyle.Primary" />
|
||||
|
||||
}
|
||||
|
||||
@code {
|
||||
private BlogPostViewModel? blogPostViewModel;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
blogPostViewModel = new();
|
||||
}
|
||||
|
||||
void OnPaste(HtmlEditorPasteEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
void OnChange(string html)
|
||||
{
|
||||
}
|
||||
|
||||
void OnInput(string html)
|
||||
{
|
||||
}
|
||||
|
||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
protected async Task HandleValidSubmit()
|
||||
{
|
||||
if (blogPostViewModel == null) return;
|
||||
|
||||
var blogPost = Mapper.Map<BlogPostViewModel, BlogPost>(blogPostViewModel);
|
||||
bool result = await BlogPostService.AddBlogPostAsync(blogPost);
|
||||
if (result)
|
||||
NavigationManager.NavigateTo("/BlogPost/");
|
||||
|
||||
}
|
||||
|
||||
private void NavigatetoBlogPostIndex() => NavigationManager.NavigateTo("/BlogPost");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
@page "/BlogPost/Delete/{id:int}"
|
||||
|
||||
<h3>Delete</h3>
|
||||
|
||||
@if (blogPostViewModel == null)
|
||||
{
|
||||
<p>Loading...</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<RadzenStack>
|
||||
<RadzenFieldset Text="Post Delete">
|
||||
<RadzenStack>
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Id" for="id" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
<RadzenTextBox id="id" class="form-control" placeholder="Id" ReadOnly=true
|
||||
Value="@blogPostViewModel.Id.ToString()" />
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Title" for="title" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
<RadzenTextBox id="title" class="form-control" placeholder="Title" ReadOnly=true
|
||||
Value="@blogPostViewModel.Title" />
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
</RadzenStack>
|
||||
|
||||
<RadzenButton Text="REMOVE" Icon="delete_forever" ButtonStyle="ButtonStyle.Danger"
|
||||
Click="RemoveButtonClick" />
|
||||
|
||||
</RadzenFieldset>
|
||||
</RadzenStack>
|
||||
|
||||
<RadzenButton Text="Back" Icon="arrow_back" Class="rz-mt-2"
|
||||
Click="NavigatetoBlogPostIndex"
|
||||
ButtonStyle="ButtonStyle.Primary" />
|
||||
|
||||
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public int id { get; set; }
|
||||
|
||||
BlogPostViewModel? blogPostViewModel;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (blogPostViewModel == null)
|
||||
{
|
||||
var blogPost = await BlogPostService.GetbyId(id);
|
||||
if (blogPost == null)
|
||||
return;
|
||||
|
||||
blogPostViewModel = Mapper.Map<BlogPost, BlogPostViewModel>(blogPost);
|
||||
}
|
||||
}
|
||||
|
||||
private async void RemoveButtonClick()
|
||||
{
|
||||
bool result = await BlogPostService.DeletebyIdAsync(id);
|
||||
if (result)
|
||||
NavigationManager.NavigateTo("/BlogPost");
|
||||
}
|
||||
|
||||
private void NavigatetoBlogPostIndex() => NavigationManager.NavigateTo("/BlogPost");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
@page "/BlogPost/Detail/{id:int}"
|
||||
|
||||
<h3>Detail</h3>
|
||||
|
||||
@if (blogPostViewModel == null)
|
||||
{
|
||||
<p>Loading...</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<RadzenStack>
|
||||
<RadzenFieldset Text="Post Detail">
|
||||
<RadzenStack>
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Id" for="id" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
<RadzenTextBox id="id" class="form-control" placeholder="Id" ReadOnly=true
|
||||
Value="@blogPostViewModel.Id.ToString()" />
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Title" for="title" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
<RadzenTextBox id="title" class="form-control" placeholder="Title" ReadOnly=true
|
||||
Value="@blogPostViewModel.Title" />
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Content" for="content" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
<RadzenTextBox id="content" class="form-control" placeholder="Content" ReadOnly=true
|
||||
Value="@blogPostViewModel.Content" />
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
</RadzenStack>
|
||||
</RadzenFieldset>
|
||||
</RadzenStack>
|
||||
|
||||
<RadzenButton Text="Back" Icon="arrow_back" Class="rz-mt-2"
|
||||
Click="NavigatetoBlogPostIndex"
|
||||
ButtonStyle="ButtonStyle.Primary" />
|
||||
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public int id { get; set; }
|
||||
|
||||
BlogPostViewModel? blogPostViewModel;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (blogPostViewModel == null)
|
||||
{
|
||||
var blogPost = await BlogPostService.GetbyId(id);
|
||||
if (blogPost == null)
|
||||
return;
|
||||
|
||||
blogPostViewModel = Mapper.Map<BlogPost, BlogPostViewModel>(blogPost);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void NavigatetoBlogPostIndex() => NavigationManager.NavigateTo("/BlogPost");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
@page "/BlogPost/Edit/{id:int}"
|
||||
|
||||
<h3>Edit</h3>
|
||||
|
||||
@if (blogPostViewModel == null)
|
||||
{
|
||||
<p>Loading...</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<RadzenStack>
|
||||
<RadzenFieldset Text="Edit Post">
|
||||
<RadzenStack Gap="2rem">
|
||||
<EditForm Context="editFormEdit" Model="@blogPostViewModel" OnValidSubmit="HandleValidSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Title" for="title" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
<InputText id="title" class="form-control" placeholder="Title"
|
||||
@bind-Value="blogPostViewModel.Title" />
|
||||
<ValidationMessage For="@(() => blogPostViewModel.Title)" />
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenRow AlignItems="AlignItems.Center" Class="rz-mb-2">
|
||||
<RadzenColumn SizeSM="12" SizeMD="2" SizeLG="2">
|
||||
<RadzenLabel Text="Content" for="content" />
|
||||
</RadzenColumn>
|
||||
<RadzenColumn SizeSM="12" SizeMD="10" SizeLG="10">
|
||||
@*
|
||||
<InputText id="content" class="form-control" placeholder="Content"
|
||||
@bind-Value="blogPostViewModel.Content" />
|
||||
<ValidationMessage For="@(() => blogPostViewModel.Content)" />
|
||||
*@
|
||||
|
||||
<RadzenHtmlEditor @bind-Value=@blogPostViewModel.Content
|
||||
Input=@OnInput Change=@OnChange
|
||||
Paste=@OnPaste Execute=@OnExecute
|
||||
UploadUrl="upload/image" />
|
||||
<ValidationMessage For="@(() => blogPostViewModel.Content)" />
|
||||
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenButton Text="Save" Icon="save"
|
||||
ButtonType="ButtonType.Submit" ButtonStyle="ButtonStyle.Success" />
|
||||
|
||||
</EditForm>
|
||||
|
||||
</RadzenStack>
|
||||
</RadzenFieldset>
|
||||
</RadzenStack>
|
||||
|
||||
<RadzenButton Text="Back" Icon="arrow_back" Class="rz-mt-2"
|
||||
Click="NavigatetoBlogPostIndex"
|
||||
ButtonStyle="ButtonStyle.Primary" />
|
||||
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public int id { get; set; }
|
||||
|
||||
BlogPostViewModel? blogPostViewModel;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (blogPostViewModel == null)
|
||||
{
|
||||
var blogPost = await BlogPostService.GetbyId(id);
|
||||
if (blogPost == null)
|
||||
return;
|
||||
|
||||
blogPostViewModel = Mapper.Map<BlogPost, BlogPostViewModel>(blogPost);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnPaste(HtmlEditorPasteEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
void OnChange(string html)
|
||||
{
|
||||
}
|
||||
|
||||
void OnInput(string html)
|
||||
{
|
||||
}
|
||||
|
||||
void OnExecute(HtmlEditorExecuteEventArgs args)
|
||||
{
|
||||
}
|
||||
|
||||
protected async Task HandleValidSubmit()
|
||||
{
|
||||
if (blogPostViewModel == null) return;
|
||||
|
||||
var blogPost = Mapper.Map<BlogPostViewModel, BlogPost>(blogPostViewModel);
|
||||
bool result = await BlogPostService.UpdateBlogPostAsync(id, blogPost);
|
||||
if (result)
|
||||
NavigationManager.NavigateTo("/BlogPost/");
|
||||
}
|
||||
|
||||
private void NavigatetoBlogPostIndex() => NavigationManager.NavigateTo("/BlogPost");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
@page "/BlogPost"
|
||||
|
||||
<PageTitle>Posts</PageTitle>
|
||||
|
||||
<RadzenRow>
|
||||
|
||||
<RadzenColumn SizeSM="12" SizeMD="12" SizeLG="4">
|
||||
|
||||
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center">
|
||||
<RadzenText Text="Posts" TextStyle="TextStyle.H5" />
|
||||
<RadzenButton Text="Create" Icon="add_circle_outline"
|
||||
Click="NavigatetoCreate"
|
||||
ButtonStyle="ButtonStyle.Success" class="rz-mb-2 rz-p-2" />
|
||||
</RadzenStack>
|
||||
|
||||
</RadzenColumn>
|
||||
|
||||
</RadzenRow>
|
||||
|
||||
<RadzenDataGrid KeyProperty="Id" IsLoading="@isLoading" ShowPagingSummary=true
|
||||
Count="@totalCount" Data="@blogPosts" LoadData="@LoadData"
|
||||
FilterPopupRenderMode="PopupRenderMode.OnDemand"
|
||||
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
|
||||
FilterMode="FilterMode.Advanced" AllowSorting="true" AllowFiltering="true"
|
||||
AllowPaging="true" PageSize="@itemPageSize" PagerHorizontalAlign="HorizontalAlign.Center"
|
||||
TItem="BlogPostViewModel" ColumnWidth="200px">
|
||||
<Columns>
|
||||
<RadzenDataGridColumn TItem="BlogPostViewModel" Property="Id" Filterable="false" Title="Id" Frozen="true" Width="30px" MinWidth="30px" TextAlign="TextAlign.Center" />
|
||||
|
||||
<RadzenDataGridColumn TItem="BlogPostViewModel" Property="Title" Title="Title" />
|
||||
<RadzenDataGridColumn TItem="BlogPostViewModel" Property="Content" Title="Content" />
|
||||
|
||||
<RadzenDataGridColumn TItem="BlogPostViewModel" Context="blogPost" Filterable="false" Sortable="false" Width="150px" TextAlign="TextAlign.Center">
|
||||
<Template Context="blogPost">
|
||||
|
||||
<RadzenRow JustifyContent="JustifyContent.Center">
|
||||
<RadzenButton Icon="pageview" ButtonStyle="ButtonStyle.Info" Variant="Variant.Flat" Size="ButtonSize.Medium"
|
||||
Click="@(args => NavigatetoDetail(blogPost.Id))" @onclick:stopPropagation="true">
|
||||
</RadzenButton>
|
||||
<RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Warning" Variant="Variant.Flat" Size="ButtonSize.Medium"
|
||||
Click="@(args => NavigatetoEdit(blogPost.Id))" @onclick:stopPropagation="true">
|
||||
</RadzenButton>
|
||||
<RadzenButton Icon="delete_forever" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium"
|
||||
Click="@(args => NavigatetoDelete(blogPost.Id))" @onclick:stopPropagation="true">
|
||||
</RadzenButton>
|
||||
</RadzenRow>
|
||||
|
||||
</Template>
|
||||
</RadzenDataGridColumn>
|
||||
</Columns>
|
||||
</RadzenDataGrid>
|
||||
|
||||
|
||||
@code {
|
||||
|
||||
const int itemPageSize = 10;
|
||||
private bool isLoading;
|
||||
private int totalCount;
|
||||
private IEnumerable<BlogPostViewModel>? blogPosts;
|
||||
|
||||
private async Task LoadData(LoadDataArgs args)
|
||||
{
|
||||
isLoading = true;
|
||||
|
||||
var result = await BlogPostService.GetBlogPostsAsync(filter: args.Filter, top: args.Top, skip: args.Skip, orderby: args.OrderBy, count: true);
|
||||
|
||||
blogPosts = Mapper.Map<IEnumerable<BlogPost>, IEnumerable<BlogPostViewModel>>(result.Result);
|
||||
totalCount = result.TotalCount;
|
||||
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private void NavigatetoCreate() => NavigationManager.NavigateTo("/BlogPost/Create");
|
||||
private void NavigatetoDetail(int id) => NavigationManager.NavigateTo($"/BlogPost/Detail/{id}");
|
||||
private void NavigatetoEdit(int id) => NavigationManager.NavigateTo($"/BlogPost/Edit/{id}");
|
||||
private void NavigatetoDelete(int id) => NavigationManager.NavigateTo($"/BlogPost/Delete/{id}");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
@using BlazorAppRadzenHtmlEditor.Data;
|
||||
@using BlazorAppRadzenHtmlEditor.Models;
|
||||
@using BlazorAppRadzenHtmlEditor.Services;
|
||||
@using BlazorAppRadzenHtmlEditor.ViewModels;
|
||||
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject BlogPostService BlogPostService
|
||||
@@ -0,0 +1,36 @@
|
||||
@page "/Error"
|
||||
@using System.Diagnostics
|
||||
|
||||
<PageTitle>Error</PageTitle>
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
|
||||
@code{
|
||||
[CascadingParameter]
|
||||
private HttpContext? HttpContext { get; set; }
|
||||
|
||||
private string? RequestId { get; set; }
|
||||
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
|
||||
protected override void OnInitialized() =>
|
||||
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@page "/"
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
||||
@@ -0,0 +1,69 @@
|
||||
@page "/PostSingle/{id:int}"
|
||||
|
||||
@using BlazorAppRadzenHtmlEditor.Data;
|
||||
@using BlazorAppRadzenHtmlEditor.Models;
|
||||
@using BlazorAppRadzenHtmlEditor.Services;
|
||||
@using BlazorAppRadzenHtmlEditor.ViewModels;
|
||||
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject BlogPostService BlogPostService
|
||||
|
||||
@if (blogPostViewModel == null)
|
||||
{
|
||||
<p>Loading...</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<RadzenStack>
|
||||
<RadzenCard Class="rz-mb-6 rz-mx-auto" Style="width: 100%; padding: 0;">
|
||||
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Start" Gap="1rem" Class="rz-p-4">
|
||||
<RadzenStack Gap="0">
|
||||
<RadzenText TextStyle="TextStyle.H5">
|
||||
<b>
|
||||
@blogPostViewModel.Title
|
||||
</b>
|
||||
</RadzenText>
|
||||
</RadzenStack>
|
||||
</RadzenStack>
|
||||
<RadzenCard class="rz-shadow-3 rz-border-radius-0 rz-p-8" style="margin-left:-15px;margin-right:-15px;">
|
||||
<RadzenRow RowGap="0">
|
||||
<RadzenColumn Size="12">
|
||||
<RadzenText TextStyle="TextStyle.Body1">
|
||||
@((MarkupString)blogPostViewModel.Content)
|
||||
</RadzenText>
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
</RadzenCard>
|
||||
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.End" Gap="0" Style="margin:15px">
|
||||
</RadzenStack>
|
||||
</RadzenCard>
|
||||
</RadzenStack>
|
||||
|
||||
<RadzenButton Text="Back" Icon="arrow_back" Class="rz-mt-2"
|
||||
Click="NavigatetoPosts"
|
||||
ButtonStyle="ButtonStyle.Primary" />
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public int id { get; set; }
|
||||
|
||||
BlogPostViewModel? blogPostViewModel;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (blogPostViewModel == null)
|
||||
{
|
||||
var blogPost = await BlogPostService.GetbyId(id);
|
||||
if (blogPost == null)
|
||||
return;
|
||||
|
||||
blogPostViewModel = Mapper.Map<Models.BlogPost, BlogPostViewModel>(blogPost);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void NavigatetoPosts() => NavigationManager.NavigateTo("/Posts");
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
@page "/Posts"
|
||||
|
||||
@using BlazorAppRadzenHtmlEditor.Data;
|
||||
@using BlazorAppRadzenHtmlEditor.Models;
|
||||
@using BlazorAppRadzenHtmlEditor.Services;
|
||||
@using BlazorAppRadzenHtmlEditor.ViewModels;
|
||||
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject BlogPostService BlogPostService
|
||||
|
||||
<PageTitle>Posts</PageTitle>
|
||||
|
||||
<RadzenDataList IsLoading=@isLoading
|
||||
LoadData="@LoadData" Count="@totalCount" Data="@blogPosts"
|
||||
TItem="BlogPostViewModel" PageSize="@itemPageSize"
|
||||
WrapItems="true" AllowPaging="true" PagerHorizontalAlign="HorizontalAlign.Center" ShowPagingSummary="true">
|
||||
<Template Context="blogpost">
|
||||
|
||||
<RadzenCard Class="rz-mb-6 rz-mx-auto" Style="width: 100%; padding: 0;">
|
||||
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.Start" Gap="1rem" Class="rz-p-4">
|
||||
<RadzenStack Gap="0">
|
||||
<RadzenText TextStyle="TextStyle.H5">
|
||||
<b>
|
||||
@blogpost.Title
|
||||
</b>
|
||||
</RadzenText>
|
||||
</RadzenStack>
|
||||
</RadzenStack>
|
||||
<RadzenCard class="rz-shadow-3 rz-border-radius-0 rz-p-8" style="margin-left:-15px;margin-right:-15px;">
|
||||
<RadzenRow RowGap="0">
|
||||
<RadzenColumn Size="12">
|
||||
<RadzenText TextStyle="TextStyle.Body1">
|
||||
@((MarkupString)blogpost.ContentShort)
|
||||
|
||||
<RadzenButton ButtonStyle="ButtonStyle.Secondary" Size="ButtonSize.ExtraSmall"
|
||||
Text="Show More..."
|
||||
Click="() => NavigatetoPostSingle(blogpost.Id)" />
|
||||
|
||||
</RadzenText>
|
||||
</RadzenColumn>
|
||||
</RadzenRow>
|
||||
</RadzenCard>
|
||||
<RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.End" Gap="0">
|
||||
<RadzenButton ButtonStyle="ButtonStyle.Primary" Text="Show Post" Style="margin:15px"
|
||||
Click="() => NavigatetoPostSingle(blogpost.Id)" />
|
||||
</RadzenStack>
|
||||
</RadzenCard>
|
||||
|
||||
</Template>
|
||||
</RadzenDataList>
|
||||
|
||||
@code {
|
||||
|
||||
const int itemPageSize = 10;
|
||||
private bool isLoading;
|
||||
private int totalCount;
|
||||
private IEnumerable<BlogPostViewModel>? blogPosts;
|
||||
|
||||
private async Task LoadData(LoadDataArgs args)
|
||||
{
|
||||
isLoading = true;
|
||||
|
||||
var result = await BlogPostService.GetBlogPostsAsync(filter: args.Filter, top: args.Top, skip: args.Skip, orderby: args.OrderBy, count: true);
|
||||
|
||||
blogPosts = Mapper.Map<IEnumerable<Models.BlogPost>, IEnumerable<BlogPostViewModel>>(result.Result);
|
||||
totalCount = result.TotalCount;
|
||||
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private void NavigatetoPostSingle(int id) => NavigationManager.NavigateTo($"/PostSingle/{id}");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<Router AppAssembly="typeof(Program).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
|
||||
@* <FocusOnNavigate RouteData="routeData" Selector="h1" /> *@
|
||||
</Found>
|
||||
</Router>
|
||||
@@ -0,0 +1,16 @@
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using static Microsoft.AspNetCore.Components.Web.RenderMode
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using BlazorAppRadzenHtmlEditor
|
||||
@using BlazorAppRadzenHtmlEditor.Components
|
||||
|
||||
@using MapsterMapper
|
||||
@using Radzen
|
||||
@using Radzen.Blazor
|
||||
|
||||
@inject IMapper Mapper
|
||||
@@ -0,0 +1,122 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace BlazorAppRadzenHtmlEditor.Controllers;
|
||||
|
||||
[DisableRequestSizeLimit]
|
||||
public partial class UploadController : Controller
|
||||
{
|
||||
private readonly IWebHostEnvironment environment;
|
||||
|
||||
public UploadController(IWebHostEnvironment environment)
|
||||
{
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
//[HttpPost("upload/single")]
|
||||
//public IActionResult Single(IFormFile file)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// // Put your code here
|
||||
// return Ok(new { Completed = true });
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// return StatusCode(500, ex.Message);
|
||||
// }
|
||||
//}
|
||||
|
||||
[HttpPost("upload/image")]
|
||||
public IActionResult Image(IFormFile file)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Used for demo purposes only
|
||||
//DeleteOldFiles();
|
||||
|
||||
var fileName = $"upload-{DateTime.Today.ToString("yyyy-MM-dd")}-{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
|
||||
|
||||
var filePath = Path.Combine(environment.WebRootPath, fileName);
|
||||
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
// Save the file
|
||||
file.CopyTo(stream);
|
||||
|
||||
// Return the URL of the file
|
||||
var url = Url.Content($"~/{fileName}");
|
||||
|
||||
return Ok(new { Url = url });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return StatusCode(500, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteOldFiles()
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(environment.WebRootPath))
|
||||
{
|
||||
var fileName = Path.GetFileName(file);
|
||||
|
||||
if (fileName.StartsWith("upload-") && !fileName.StartsWith($"upload-{DateTime.Today.ToString("yyyy-MM-dd")}"))
|
||||
{
|
||||
try
|
||||
{
|
||||
System.IO.File.Delete(file);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//[HttpPost("upload/multiple")]
|
||||
//public IActionResult Multiple(IFormFile[] files)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// // Put your code here
|
||||
// return StatusCode(200);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// return StatusCode(500, ex.Message);
|
||||
// }
|
||||
//}
|
||||
|
||||
//[HttpPost("upload/{id}")]
|
||||
//public IActionResult Post(IFormFile[] files, int id)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// // Put your code here
|
||||
// return StatusCode(200);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// return StatusCode(500, ex.Message);
|
||||
// }
|
||||
//}
|
||||
|
||||
//[HttpPost("upload/specific")]
|
||||
//public IActionResult Specific(IFormFile myName)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// // Put your code here
|
||||
// return Ok(new { Completed = true });
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// return StatusCode(500, ex.Message);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using BlazorAppRadzenHtmlEditor.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BlazorAppRadzenHtmlEditor.Data;
|
||||
|
||||
public class ApplicationDbContext : DbContext
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<BlogPost> BlogPosts => Set<BlogPost>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using BlazorAppRadzenHtmlEditor.Models;
|
||||
|
||||
namespace BlazorAppRadzenHtmlEditor.Data;
|
||||
|
||||
public class SeedData
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public SeedData(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task CreateInitialData()
|
||||
{
|
||||
var posts = GetAllBlogPosts();
|
||||
await _context.BlogPosts.AddRangeAsync(posts);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private static IEnumerable<BlogPost> GetAllBlogPosts()
|
||||
{
|
||||
List<BlogPost> posts = new();
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
BlogPost post = new() { Id = i + 1, Title = titles[i], Content = contents[i % 6] };
|
||||
posts.Add(post);
|
||||
}
|
||||
|
||||
return posts;
|
||||
}
|
||||
|
||||
private static readonly string[] titles = {
|
||||
"Introduction to Object-Oriented Programming",
|
||||
"Mastering Data Structures and Algorithms",
|
||||
"Building Web Applications with ASP.NET",
|
||||
"Creating Mobile Apps with Xamarin",
|
||||
"Exploring Artificial Intelligence and Machine Learning",
|
||||
"Understanding Functional Programming Concepts",
|
||||
"Developing Games with Unity",
|
||||
"Securing Web Applications from Cyber Attacks",
|
||||
"Optimizing Code Performance for Better Efficiency",
|
||||
"Implementing Design Patterns in Software Development",
|
||||
"Testing and Debugging Strategies for Reliable Software",
|
||||
"Working with Databases and SQL",
|
||||
"Building Responsive User Interfaces with HTML and CSS",
|
||||
"Exploring Cloud Computing and Serverless Architecture",
|
||||
"Developing Cross-Platform Applications with React Native",
|
||||
"Introduction to Internet of Things (IoT)",
|
||||
"Creating Scalable Microservices with Docker and Kubernetes",
|
||||
"Understanding Network Protocols and TCP/IP",
|
||||
"Building RESTful APIs with Node.js and Express",
|
||||
"Exploring Big Data Analytics and Apache Hadoop",
|
||||
"Mastering Version Control with Git and GitHub",
|
||||
"Developing Desktop Applications with WPF",
|
||||
"Securing Mobile Applications from Malicious Attacks",
|
||||
"Optimizing Database Performance with Indexing",
|
||||
"Implementing Continuous Integration and Deployment",
|
||||
"Testing Mobile Apps on Different Platforms",
|
||||
"Working with NoSQL Databases like MongoDB",
|
||||
"Building Progressive Web Apps with React",
|
||||
"Exploring Quantum Computing and Quantum Algorithms",
|
||||
"Introduction to Cybersecurity and Ethical Hacking",
|
||||
"Creating Chatbots with Natural Language Processing",
|
||||
"Understanding Software Development Life Cycle",
|
||||
"Developing Augmented Reality (AR) Applications",
|
||||
"Securing Web APIs with OAuth and JWT",
|
||||
"Optimizing Front-End Performance for Better User Experience",
|
||||
"Implementing Machine Learning Models with TensorFlow",
|
||||
"Testing Web Applications for Cross-Browser Compatibility",
|
||||
"Working with Blockchain Technology and Smart Contracts",
|
||||
"Building Real-Time Applications with SignalR",
|
||||
"Exploring Cryptography and Encryption Techniques",
|
||||
"Introduction to Agile Software Development",
|
||||
"Creating Voice User Interfaces with Amazon Alexa",
|
||||
"Understanding Web Accessibility and Inclusive Design",
|
||||
"Developing Natural Language Processing Applications",
|
||||
"Securing Cloud Infrastructure and Services",
|
||||
"Optimizing Backend Performance for Scalability",
|
||||
"Implementing Continuous Monitoring and Alerting",
|
||||
"Testing APIs with Postman and Swagger",
|
||||
"Working with Data Visualization Libraries like D3.js",
|
||||
"Building E-commerce Applications with Shopify",
|
||||
"Exploring Robotic Process Automation (RPA)",
|
||||
"Introduction to DevOps and CI/CD Pipelines"
|
||||
};
|
||||
|
||||
private static readonly string[] contents = new string[]
|
||||
{
|
||||
|
||||
"<div><img src=\"/upload-2024-05-12-3d2c9bc2-4ab6-4ede-acc9-4b6763081996.jpeg\" width=\"100\" style=\"border-radius: 25px;\"></div> \r\n<span style=\"font-weight: bold;\">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span> \r\nDuis ultricies posuere leo nec ornare. Etiam eu tempus tellus. Aliquam bibendum justo diam, et tincidunt ipsum tempus eu. Aenean vel sem ante. Vivamus maximus ornare imperdiet. Curabitur varius, arcu vitae pretium lobortis, dolor nisi facilisis orci, nec elementum nibh mi vel nisl. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed a venenatis nisi. Nullam sit amet ipsum maximus, tempus mi eget, sollicitudin diam.\r\n<div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-3d2c9bc2-4ab6-4ede-acc9-4b6763081996.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Sed faucibus, ex et pulvinar vulputate, erat diam sollicitudin odio, ut euismod enim odio nec nunc.</span> \r\nCurabitur nec dolor sem. Vivamus euismod mi risus, in bibendum erat cursus sed. Integer et nisi metus. In hac habitasse platea dictumst. Ut faucibus pretium sapien non ullamcorper. Etiam pretium mollis neque. Phasellus congue suscipit elit vitae porttitor. Mauris eget tellus non eros ultricies vehicula. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Fusce sed tortor in enim luctus sagittis et consequat odio. Phasellus eu sapien quis turpis consequat tempus at quis mi. Aenean non justo lorem. Morbi tempus nec arcu a ullamcorper.\r\n<br></div><div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-b43d01df-f3d0-42d0-9fe2-1844c78ae414.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Vestibulum non eros risus.</span> \r\nSuspendisse orci diam, rhoncus vitae sollicitudin eu, porta at mauris. Mauris varius euismod dictum. Donec turpis diam, ultrices sed libero sit amet, tempor cursus urna. Pellentesque ut mattis nisi. Aenean luctus at sem id facilisis. Suspendisse tempus pellentesque sapien nec aliquam. Sed id mi bibendum, posuere elit in, viverra purus. Etiam id ultricies elit. Praesent a molestie felis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed vulputate ex id neque congue, id condimentum dui dignissim. Nulla pellentesque libero id leo fringilla bibendum. Suspendisse id aliquam quam.\r\n<br></div>",
|
||||
|
||||
"<div><img src=\"/upload-2024-05-12-6777339d-9aa3-4f6a-af0d-015e671fd67b.jpeg\" width=\"100\" style=\"border-radius: 25px;\"></div> \r\n<span style=\"font-weight: bold;\">Duis facilisis nisi at sapien mattis, eu tincidunt massa aliquam.</span> \r\nAenean eu erat pretium, tempus massa at, auctor lectus. Cras faucibus turpis ex, ut pretium diam condimentum vitae. Fusce blandit nisl at suscipit maximus. Donec tristique tellus dolor, et sollicitudin tellus porttitor ac. Suspendisse iaculis molestie congue. Mauris non mattis urna. Integer cursus orci arcu, non pellentesque felis porttitor sit amet. Nulla facilisi.\r\n<div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-6777339d-9aa3-4f6a-af0d-015e671fd67b.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Duis consequat mi nec diam faucibus tincidunt.</span> \r\nNunc ut feugiat dui. Proin malesuada nisl sit amet nulla scelerisque, in mollis mi rhoncus. Ut vel tristique lorem, ut feugiat enim. Pellentesque vel sapien feugiat, porttitor elit consequat, tristique eros. Aenean feugiat ex eget libero aliquet, a egestas dui ornare. Vestibulum dolor ligula, molestie eu lacus quis, pulvinar egestas turpis. Suspendisse a lobortis leo, at finibus magna. Nam nec tristique nisi, blandit dapibus neque. Aenean in velit a leo condimentum eleifend. Duis posuere urna lacus, id blandit nisl laoreet sed. Curabitur ligula turpis, pellentesque in purus eu, tincidunt posuere libero. Nulla finibus, erat ac ultrices posuere, tellus enim blandit nisl, at consectetur tellus nibh eget est. Donec gravida tortor quis fringilla pharetra. Pellentesque aliquam pellentesque risus nec rhoncus. Nunc mattis elit tellus, vel congue lectus mollis sed.\r\n<br></div><div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-5cb5f731-72ee-4b10-831c-f976eed6fef0.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Aenean tristique, nulla ac vehicula dignissim, turpis est accumsan urna, sed finibus lacus dui eget nulla.</span> \r\nSed finibus elit magna, vitae iaculis dui ornare a. Praesent tempor ligula sapien, id hendrerit diam cursus eget. Nam eu fermentum justo. Etiam lobortis lacinia erat, in dapibus est lacinia eu. Mauris sed quam sapien. Aenean maximus, nibh tincidunt tincidunt molestie, nisl arcu convallis mauris, at accumsan magna ex eu libero. Praesent vel vehicula massa. Suspendisse sodales augue id dui rutrum, at commodo lectus elementum. Nulla sed ante viverra, rhoncus erat ac, varius sem.\r\n<br></div>",
|
||||
|
||||
"<div><img src=\"/upload-2024-05-12-221b63e2-d7c8-4d7b-aa24-dd0c54461015.jpeg\" width=\"100\" style=\"border-radius: 25px;\"></div> \r\n<span style=\"font-weight: bold;\">Mauris scelerisque quam at posuere imperdiet.</span> \r\nMorbi porta vitae lacus ac hendrerit. Suspendisse posuere nulla ut finibus aliquet. Integer pretium pulvinar erat in efficitur. Proin justo ex, tincidunt eu congue non, mollis et nisl. Nunc nec rhoncus leo, eget eleifend diam. Phasellus feugiat nisl nec enim volutpat pulvinar. Maecenas ac urna in eros imperdiet dictum.\r\n<div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-221b63e2-d7c8-4d7b-aa24-dd0c54461015.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Duis varius in mauris id posuere.</span> \r\nEtiam lobortis purus augue, vitae ultricies purus consequat maximus. Mauris tincidunt molestie ligula, sit amet pulvinar nibh consectetur sit amet. Aliquam pellentesque malesuada orci id maximus. Curabitur lacinia, orci sed consectetur dignissim, ex dolor pulvinar orci, a consequat massa lectus vitae ipsum. Duis et augue vel odio placerat feugiat vitae id mauris. In mi turpis, consequat quis gravida sit amet, suscipit sit amet felis. Nam feugiat lobortis lectus ac bibendum. Aliquam id consequat sem, vel vehicula turpis. Pellentesque id dui malesuada, tincidunt felis id, faucibus mauris. Vestibulum ut ligula in enim vulputate euismod. Cras vel diam egestas, ultricies nisl ut, ornare magna.\r\n<br></div><div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-e627b879-a260-470d-b0fb-527ddc44af7d.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Vivamus erat diam, rutrum at nibh id, rhoncus tincidunt nunc.</span> \r\nMorbi sed libero condimentum, pharetra mauris id, facilisis felis. Pellentesque varius hendrerit rhoncus. In hac habitasse platea dictumst. Phasellus ex nisl, tincidunt quis lacus ac, suscipit sollicitudin mi. Nunc ultrices tempor mi. Aliquam ante urna, vestibulum in pellentesque nec, tempus sed sem. Nunc elementum arcu pretium nisl euismod condimentum sed eget urna. Praesent vitae tellus quis ante sollicitudin bibendum. Praesent a leo eros. Praesent pellentesque, odio sed consectetur maximus, diam nibh scelerisque nulla, et semper nisl libero consectetur ex. Vestibulum eget placerat nunc. Curabitur posuere justo quis massa venenatis, sit amet aliquam nisi scelerisque. Proin dignissim dui vulputate, dignissim nisl ac, mattis nibh.\r\n<br></div>",
|
||||
|
||||
"<div><img src=\"/upload-2024-05-12-ef3cb0a3-020e-4a00-8a79-f1706550f445.jpeg\" width=\"100\" style=\"border-radius: 25px;\"></div> \r\n<span style=\"font-weight: bold;\">Donec sed sapien in sapien imperdiet vestibulum in eget risus.</span> \r\nNulla metus purus, vehicula in neque id, ullamcorper finibus eros. Maecenas felis neque, molestie vitae urna at, lacinia sodales metus. Etiam cursus mi eget justo tincidunt, et cursus tortor efficitur. Aliquam fermentum lacinia ipsum, et maximus ante mattis vel. Cras rhoncus id dui sit amet finibus. Quisque ac tempus augue. Vestibulum at rhoncus velit. Nullam eget nulla bibendum, suscipit augue sed, accumsan nulla. Nam suscipit nunc id ipsum convallis, et egestas ipsum dictum. Integer at ante augue. Aenean sit amet cursus risus. Duis vel risus non mauris accumsan dictum.\r\n<div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-ef3cb0a3-020e-4a00-8a79-f1706550f445.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Cras semper eros a scelerisque vehicula.</span> \r\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Proin malesuada eros non sem fermentum, in auctor sem venenatis. Sed sollicitudin rhoncus orci, vitae fermentum leo condimentum eget. Mauris id lacinia neque. Etiam arcu purus, laoreet ac iaculis eu, sagittis a libero. Phasellus in nisl sit amet urna mattis bibendum. In condimentum pharetra est.\r\n<br></div><div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-35621ccb-ff3c-46c8-b510-405d9abb87ca.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Morbi posuere felis pretium, fringilla lacus a, ultricies urna.</span> \r\nCurabitur non diam vel dolor commodo dapibus ac vel urna. Duis dui ligula, sodales id lorem in, maximus molestie turpis. Donec vitae urna rutrum, cursus diam sed, vestibulum dui. Fusce id aliquet justo. Mauris lobortis, lacus ut eleifend lobortis, orci odio sollicitudin leo, ac sodales dui metus eget sapien. Etiam rutrum lorem id blandit vulputate. Vivamus suscipit augue sed augue efficitur commodo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec vitae orci non sem molestie fermentum. Nunc lobortis diam ligula. Phasellus imperdiet est vel sodales lacinia. Sed at dui eu magna lacinia fermentum.\r\n<br></div>",
|
||||
|
||||
"<div><img src=\"/upload-2024-05-12-6bb077bb-4a31-4f8c-b275-499ca2ec6e4b.jpeg\" width=\"100\" style=\"border-radius: 25px;\"></div> \r\n<span style=\"font-weight: bold;\">Nam ac massa vel ipsum consequat pretium et sit amet erat.</span> \r\nAenean risus lectus, varius a dolor quis, auctor accumsan felis. Donec dignissim quam in lacus auctor, a luctus mauris suscipit. Donec risus tellus, maximus nec odio vel, faucibus aliquet eros. Integer ut elit quis lacus vehicula consequat. Etiam porta ornare varius. Praesent non hendrerit neque. Vestibulum vehicula elementum libero quis interdum. Aliquam at nulla nisi. Ut vulputate lacus eget tortor pretium, vel luctus orci commodo.\r\n<div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-6bb077bb-4a31-4f8c-b275-499ca2ec6e4b.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Nunc ut tortor maximus, dapibus sem vel, tincidunt ligula.</span> \r\nSuspendisse sed tortor magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec at urna metus. Integer at maximus sapien, vitae imperdiet tellus. Nunc mollis ultrices rhoncus. Nullam ullamcorper ante sit amet sollicitudin aliquam. Proin sit amet urna non nulla hendrerit tempus. Proin sodales enim at est interdum aliquam.\r\n<br></div><div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-bd2672cb-495e-41b9-aa3d-6e52189f5876.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Sed egestas blandit nisl, non gravida est.</span> \r\nPraesent aliquam auctor nunc, a blandit lorem varius at. Vestibulum dictum turpis sit amet lorem iaculis, posuere tempor turpis scelerisque. Pellentesque nec lacus mauris. Aenean tincidunt facilisis mauris sit amet sollicitudin. Vivamus et ligula eu metus tempus facilisis nec sed ligula. Nam ultricies urna non elit suscipit placerat. Etiam imperdiet egestas sem nec lacinia. Fusce malesuada neque in tortor sodales, vitae sagittis purus eleifend.\r\n<br></div>",
|
||||
|
||||
"<div><img src=\"/upload-2024-05-12-1d87cac3-25db-4ef2-9646-0f57d4ea3bcd.jpeg\" width=\"100\" style=\"border-radius: 25px;\"></div> \r\n<span style=\"font-weight: bold;\">Cras nec nulla sed nulla elementum imperdiet.</span> \r\nNulla dapibus eget augue id ullamcorper. Donec euismod fringilla ante, a scelerisque arcu. Nulla facilisi. Nullam dolor turpis, ornare nec molestie non, volutpat sed est. Sed nulla sapien, dignissim sit amet ex eu, tempor pharetra enim. Vestibulum ac augue vel mi egestas ullamcorper. Ut at lectus congue, viverra eros eu, placerat ex. Pellentesque iaculis venenatis sapien, vel congue tortor. In hac habitasse platea dictumst.\r\n<div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-1d87cac3-25db-4ef2-9646-0f57d4ea3bcd.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Ut porta venenatis nulla, eu laoreet nisl interdum dignissim.</span> \r\nPraesent in porttitor nulla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam et pellentesque turpis, non venenatis orci. Sed a bibendum odio. Pellentesque eget nisi nec nisl varius porta eget quis metus. Sed iaculis justo pharetra est interdum, sit amet dignissim diam auctor. Maecenas et augue velit. Maecenas nec varius mi. Vivamus viverra metus sed nulla tristique, vitae lacinia nunc commodo. Integer id lorem feugiat, auctor nibh sed, viverra mauris. Fusce ac luctus nisi. Aenean sit amet dolor laoreet, laoreet tortor eget, scelerisque nisi. Sed auctor rhoncus rutrum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris at mollis ligula.\r\n<br></div><div><br></div>\r\n<div style=\"text-align: center;\">\r\n<img src=\"/upload-2024-05-12-a8425c11-a159-40a1-92c4-d353d9ae068d.jpeg\" width=\"250\" style=\"border-radius: 25px;\">\r\n<br></div><div><br></div><div>\r\n<span style=\"font-weight: bold;\">Interdum et malesuada fames ac ante ipsum primis in faucibus.</span> \r\nUt ut tincidunt elit. Mauris ultrices nisi in eros varius, semper feugiat sapien euismod. Suspendisse laoreet molestie urna et tincidunt. Etiam commodo lacus a dignissim ornare. Aenean eget consequat purus. In hac habitasse platea dictumst. Integer dapibus nibh vel est gravida, congue tempor neque venenatis.\r\n<br></div>",
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace BlazorAppRadzenHtmlEditor.Models;
|
||||
|
||||
public class BlogPost
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using BlazorAppRadzenHtmlEditor.Components;
|
||||
using BlazorAppRadzenHtmlEditor.Data;
|
||||
using BlazorAppRadzenHtmlEditor.Services;
|
||||
using BlazorAppRadzenHtmlEditor.ViewModels;
|
||||
using Mapster;
|
||||
using MapsterMapper;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Radzen;
|
||||
using System.Reflection;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||
options.UseInMemoryDatabase("ConnectionInMemory")
|
||||
);
|
||||
builder.Services.AddScoped<SeedData>();
|
||||
builder.Services.AddScoped<BlogPostService>();
|
||||
|
||||
// Radzen Services
|
||||
builder.Services.AddScoped<DialogService>();
|
||||
builder.Services.AddScoped<NotificationService>();
|
||||
builder.Services.AddScoped<TooltipService>();
|
||||
builder.Services.AddScoped<ContextMenuService>();
|
||||
|
||||
// Add mapster mapper
|
||||
builder.Services.AddMapster();
|
||||
|
||||
builder.Services.CreateDatabase().GetAwaiter().GetResult();
|
||||
|
||||
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddControllersWithViews();
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.Configure<Microsoft.AspNetCore.Http.Features.FormOptions>(options =>
|
||||
{
|
||||
options.MultipartBodyLengthLimit = long.MaxValue;
|
||||
});
|
||||
builder.Services.AddRazorComponents()
|
||||
.AddInteractiveServerComponents();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseExceptionHandler("/Error", createScopeForErrors: true);
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseAntiforgery();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
app.MapRazorComponents<App>()
|
||||
.AddInteractiveServerRenderMode();
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static async Task CreateDatabase(this IServiceCollection services)
|
||||
{
|
||||
using (IServiceScope tmp = services.BuildServiceProvider().CreateScope())
|
||||
{
|
||||
await using var _context = tmp.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
var seedData = tmp.ServiceProvider.GetRequiredService<SeedData>();
|
||||
await seedData.CreateInitialData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MapsterConfiguration
|
||||
{
|
||||
public static void AddMapster(this IServiceCollection services)
|
||||
{
|
||||
var typeAdapterConfig = TypeAdapterConfig.GlobalSettings;
|
||||
Assembly applicationAssembly = typeof(BaseViewModel<,>).Assembly;
|
||||
typeAdapterConfig.Scan(applicationAssembly);
|
||||
|
||||
var mapperConfig = new Mapper(typeAdapterConfig);
|
||||
services.AddSingleton<IMapper>(mapperConfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using BlazorAppRadzenHtmlEditor.Data;
|
||||
using BlazorAppRadzenHtmlEditor.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Radzen;
|
||||
using System.Linq.Dynamic.Core;
|
||||
|
||||
namespace BlazorAppRadzenHtmlEditor.Services;
|
||||
|
||||
public class BlogPostService
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public BlogPostService(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public Task<BlogPost?> GetbyId(int id)
|
||||
{
|
||||
return _context.BlogPosts.FirstOrDefaultAsync(x => x.Id == id);
|
||||
}
|
||||
|
||||
public async Task<(IEnumerable<BlogPost> Result, int TotalCount)> GetBlogPostsAsync(string? filter = default, int? top = default, int? skip = default, string? orderby = default, string? expand = default, string? select = default, bool? count = default)
|
||||
{
|
||||
var query = _context.BlogPosts.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(filter))
|
||||
query = query.Where(filter);
|
||||
|
||||
if (!string.IsNullOrEmpty(orderby))
|
||||
query = query.OrderBy(orderby);
|
||||
|
||||
int totalCount = 0;
|
||||
if (count == true)
|
||||
totalCount = query.Count();
|
||||
|
||||
IEnumerable<BlogPost>? result;
|
||||
if (skip == null || top == null)
|
||||
result = await query.ToListAsync();
|
||||
else
|
||||
result = await query.Skip(skip.Value).Take(top.Value).ToListAsync();
|
||||
|
||||
return (result, totalCount);
|
||||
}
|
||||
|
||||
public async Task<bool> AddBlogPostAsync(BlogPost blogPost)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _context.BlogPosts.AddAsync(blogPost);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateBlogPostAsync(int id, BlogPost blogPost)
|
||||
{
|
||||
try
|
||||
{
|
||||
var oldBlogPost = _context.BlogPosts.FirstOrDefault(x => x.Id == id);
|
||||
if (oldBlogPost == null) return false;
|
||||
|
||||
oldBlogPost.Title = blogPost.Title;
|
||||
oldBlogPost.Content = blogPost.Content;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> DeletebyIdAsync(int id)
|
||||
{
|
||||
var blogPost = await _context.BlogPosts.FirstOrDefaultAsync(x => x.Id == id);
|
||||
if (blogPost == null)
|
||||
return false;
|
||||
|
||||
_context.BlogPosts.Remove(blogPost);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Mapster;
|
||||
|
||||
namespace BlazorAppRadzenHtmlEditor.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// Model <-> ViewModel Mapping
|
||||
/// </summary>
|
||||
/// <typeparam name="TViewModel">ViewModel</typeparam>
|
||||
/// <typeparam name="TModel">Model</typeparam>
|
||||
public abstract class BaseViewModel<TViewModel, TModel> : IRegister
|
||||
where TViewModel : class, new()
|
||||
where TModel : class, new()
|
||||
{
|
||||
|
||||
public TModel ToModel()
|
||||
{
|
||||
return this.Adapt<TModel>();
|
||||
}
|
||||
|
||||
public TModel ToModel(TModel model)
|
||||
{
|
||||
return (this as TViewModel).Adapt(model);
|
||||
}
|
||||
|
||||
public static TViewModel FromModel(TModel model)
|
||||
{
|
||||
return model.Adapt<TViewModel>();
|
||||
}
|
||||
|
||||
private TypeAdapterConfig Config { get; set; }
|
||||
|
||||
public virtual void AddCustomMappings() { }
|
||||
|
||||
|
||||
protected TypeAdapterSetter<TViewModel, TModel> SetCustomMappings()
|
||||
=> Config.ForType<TViewModel, TModel>();
|
||||
|
||||
protected TypeAdapterSetter<TModel, TViewModel> SetCustomMappingsInverse()
|
||||
=> Config.ForType<TModel, TViewModel>();
|
||||
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
Config = config;
|
||||
AddCustomMappings();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using BlazorAppRadzenHtmlEditor.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BlazorAppRadzenHtmlEditor.ViewModels;
|
||||
|
||||
public class BlogPostViewModel : BaseViewModel<BlogPostViewModel, BlogPost>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required(AllowEmptyStrings = false, ErrorMessage = "Title can not be empty")]
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
[Required(AllowEmptyStrings = false, ErrorMessage = "Content can not be empty")]
|
||||
public string Content { get; set; } = string.Empty;
|
||||
|
||||
public string TitleShort { get => this.Title.Length > 50 ? this.Title.Substring(0, 50) : this.Title; }
|
||||
public string ContentShort { get => this.Content.Length > 500 ? this.Content.Substring(0, 500) : this.Content; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
7
src/BlazorAppRadzenHtmlEditor/BlazorAppRadzenHtmlEditor/wwwroot/bootstrap/bootstrap.min.css
vendored
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 290 KiB |
|
After Width: | Height: | Size: 238 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 293 KiB |
|
After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 342 KiB |
|
After Width: | Height: | Size: 261 KiB |
|
After Width: | Height: | Size: 372 KiB |
|
After Width: | Height: | Size: 305 KiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 429 KiB |
|
After Width: | Height: | Size: 338 KiB |
|
After Width: | Height: | Size: 312 KiB |
|
After Width: | Height: | Size: 357 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 228 KiB |
|
After Width: | Height: | Size: 316 KiB |