Browse Source

Made blazor server side basic theme (initially) working

pull/8074/head
Halil İbrahim Kalkan 5 years ago
parent
commit
bf9b0544eb
  1. 13
      framework/src/Volo.Abp.AspNetCore.Components.UI.BasicTheme/AbpAspNetCoreComponentsUIBasicThemeModule.cs
  2. 15
      framework/src/Volo.Abp.AspNetCore.Components.UI.Theming/AbpAspNetCoreComponentsUiThemingModule.cs
  3. 90
      framework/src/Volo.Abp.AspNetCore.Components.UI/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpComponentsBuilderExtensions.cs
  4. 7
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo.Abp.AspNetCore.Components.UI.csproj
  5. 65
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/AbpAspNetCoreComponentsUIModule.cs
  6. 67
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/ComponentsCachedApplicationConfigurationClient.cs
  7. 23
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/ComponentsCurrentPrincipalAccessor.cs
  8. 9
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/ExceptionHandling/UserExceptionInformer.cs
  9. 11
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/MultiTenancy/ComponentsCurrentTenantAccessor.cs
  10. 70
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/MultiTenancy/ComponentsRemoteTenantStore.cs
  11. 35
      framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/MultiTenancy/ComponentsRemoteTenantStoreCache.cs
  12. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ApplicationConfigurationCache.cs
  13. 7
      framework/src/Volo.Abp.BlazoriseUI/AbpBlazoriseModule.cs
  14. 2
      framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj
  15. 1
      test/BlazorServerSide/AbpBlazorServerDemo/AbpBlazorServerDemo.csproj
  16. 14
      test/BlazorServerSide/AbpBlazorServerDemo/AbpBlazorServerDemoModule.cs
  17. 10
      test/BlazorServerSide/AbpBlazorServerDemo/App.razor
  18. 1
      test/BlazorServerSide/AbpBlazorServerDemo/Pages/_Host.cshtml

13
framework/src/Volo.Abp.AspNetCore.Components.UI.BasicTheme/AbpAspNetCoreComponentsUIBasicThemeModule.cs

@ -0,0 +1,13 @@
using Volo.Abp.AspNetCore.Components.UI.Theming;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Components.UI.BasicTheme
{
[DependsOn(
typeof(AbpAspNetCoreComponentsUiThemingModule)
)]
public class AbpAspNetCoreComponentsUiBasicThemeModule : AbpModule
{
}
}

15
framework/src/Volo.Abp.AspNetCore.Components.UI.Theming/AbpAspNetCoreComponentsUiThemingModule.cs

@ -0,0 +1,15 @@
using Volo.Abp.BlazoriseUI;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Components.UI.Theming
{
[DependsOn(
typeof(AbpBlazoriseUIModule),
typeof(AbpUiNavigationModule)
)]
public class AbpAspNetCoreComponentsUiThemingModule : AbpModule
{
}
}

90
framework/src/Volo.Abp.AspNetCore.Components.UI/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpComponentsBuilderExtensions.cs

@ -1,90 +0,0 @@
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.AspNetCore.Components.UI;
using Volo.Abp.AspNetCore.Components.UI.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.Client;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Modularity;
namespace Microsoft.AspNetCore.Components.UI.Hosting
{
public static class AbpComponentsBuilderExtensions
{
//public static IAbpApplicationWithExternalServiceProvider AddApplication<TStartupModule>(
// [NotNull] this IServiceCollection services
// /*Action<AbpWebAssemblyApplicationCreationOptions> options*/)
// where TStartupModule : IAbpModule
//{
// Check.NotNull(services, nameof(services));
// // Related this commit(https://github.com/dotnet/aspnetcore/commit/b99d805bc037fcac56afb79abeb7d5a43141c85e)
// // Microsoft.AspNetCore.Blazor.BuildTools has been removed in net 5.0.
// // This call may be removed when we find a suitable solution.
// // System.Runtime.CompilerServices.AsyncStateMachineAttribute
// Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add<AsyncStateMachineAttribute>();
// services.AddSingleton<IConfiguration>(builder.Configuration);
// services.AddSingleton(builder);
// var application = services.AddApplication<TStartupModule>(opts =>
// {
// options?.Invoke(new AbpAspNetCoreApplicationCreationOptions(builder, opts));
// });
// return application;
//}
public static async Task InitializeAsync(
[NotNull] this IAbpApplicationWithExternalServiceProvider application,
[NotNull] IServiceProvider serviceProvider)
{
Check.NotNull(application, nameof(application));
Check.NotNull(serviceProvider, nameof(serviceProvider));
var serviceProviderAccessor = (ComponentsClientScopeServiceProviderAccessor)
serviceProvider.GetRequiredService<IClientScopeServiceProviderAccessor>();
serviceProviderAccessor.ServiceProvider = serviceProvider;
application.Initialize(serviceProvider);
using (var scope = serviceProvider.CreateScope())
{
await InitializeModulesAsync(scope.ServiceProvider);
await SetCurrentLanguageAsync(scope);
}
}
private static async Task InitializeModulesAsync(IServiceProvider serviceProvider)
{
foreach (var service in serviceProvider.GetServices<IAsyncInitialize>())
{
await service.InitializeAsync();
}
}
private static async Task SetCurrentLanguageAsync(IServiceScope scope)
{
var configurationClient = scope.ServiceProvider.GetRequiredService<ICachedApplicationConfigurationClient>();
var utilsService = scope.ServiceProvider.GetRequiredService<IAbpUtilsService>();
var configuration = configurationClient.Get();
var cultureName = configuration.Localization?.CurrentCulture?.CultureName;
if (!cultureName.IsNullOrEmpty())
{
var culture = new CultureInfo(cultureName);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
}
if (CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft)
{
await utilsService.AddClassToTagAsync("body", "rtl");
}
}
}
}

7
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo.Abp.AspNetCore.Components.UI.csproj

@ -16,7 +16,6 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.Client.Common\Volo.Abp.AspNetCore.Mvc.Client.Common.csproj" />
<ProjectReference Include="..\Volo.Abp.UI\Volo.Abp.UI.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components\Volo.Abp.AspNetCore.Components.csproj" />
</ItemGroup>
@ -26,9 +25,5 @@
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="$(MicrosoftPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Microsoft\Extensions\DependencyInjection\" />
</ItemGroup>
</Project>

65
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/AbpAspNetCoreComponentsUIModule.cs

@ -1,41 +1,30 @@
//using Microsoft.AspNetCore.Components;
//using Microsoft.Extensions.DependencyInjection;
//using Microsoft.Extensions.DependencyInjection.Extensions;
//using Microsoft.Extensions.Logging;
//using Volo.Abp.AspNetCore.Components.DependencyInjection;
//using Volo.Abp.AspNetCore.Components.UI.ExceptionHandling;
//using Volo.Abp.AspNetCore.Mvc.Client;
//using Volo.Abp.Http.Client;
//using Volo.Abp.Modularity;
//using Volo.Abp.UI;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.AspNetCore.Components.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.UI;
//namespace Volo.Abp.AspNetCore.Components.UI
//{
// [DependsOn(
// typeof(AbpAspNetCoreMvcClientCommonModule),
// typeof(AbpUiModule),
// typeof(AbpAspNetCoreComponentsModule)
// )]
// public class AbpAspNetCoreComponentsUIModule : AbpModule
// {
// public override void PreConfigureServices(ServiceConfigurationContext context)
// {
// PreConfigure<AbpHttpClientBuilderOptions>(options =>
// {
// options.ProxyClientBuildActions.Add((_, builder) =>
// {
// builder.AddHttpMessageHandler<AbpBlazorClientHttpMessageHandler>();
// });
// });
// }
namespace Volo.Abp.AspNetCore.Components.UI
{
[DependsOn(
typeof(AbpUiModule),
typeof(AbpAspNetCoreComponentsModule)
)]
public class AbpAspNetCoreComponentsUIModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
// public override void ConfigureServices(ServiceConfigurationContext context)
// {
// context.Services.Replace(ServiceDescriptor.Transient<IComponentActivator, ServiceProviderComponentActivator>());
}
// //context.Services
// // .GetHostBuilder().Logging
// // .AddProvider(new AbpExceptionHandlingLoggerProvider(context.Services));
// }
// }
//}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.Replace(ServiceDescriptor.Transient<IComponentActivator, ServiceProviderComponentActivator>());
//context.Services
// .GetHostBuilder().Logging
// .AddProvider(new AbpExceptionHandlingLoggerProvider(context.Services));
}
}
}

67
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/ComponentsCachedApplicationConfigurationClient.cs

@ -1,67 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.AspNetCore.Mvc.Client;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.DynamicProxying;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.Components.UI
{
[ExposeServices(
typeof(ComponentsCachedApplicationConfigurationClient),
typeof(ICachedApplicationConfigurationClient),
typeof(IAsyncInitialize)
)]
public class ComponentsCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency
{
protected IHttpClientProxy<IAbpApplicationConfigurationAppService> Proxy { get; }
protected ApplicationConfigurationCache Cache { get; }
protected ICurrentTenantAccessor CurrentTenantAccessor { get; }
public ComponentsCachedApplicationConfigurationClient(
IHttpClientProxy<IAbpApplicationConfigurationAppService> proxy,
ApplicationConfigurationCache cache,
ICurrentTenantAccessor currentTenantAccessor)
{
Proxy = proxy;
Cache = cache;
CurrentTenantAccessor = currentTenantAccessor;
}
public virtual async Task InitializeAsync()
{
var configurationDto = await Proxy.Service.GetAsync();
Cache.Set(configurationDto);
CurrentTenantAccessor.Current = new BasicTenantInfo(
configurationDto.CurrentTenant.Id,
configurationDto.CurrentTenant.Name
);
}
public virtual Task<ApplicationConfigurationDto> GetAsync()
{
return Task.FromResult(GetConfigurationByChecking());
}
public virtual ApplicationConfigurationDto Get()
{
return GetConfigurationByChecking();
}
private ApplicationConfigurationDto GetConfigurationByChecking()
{
var configuration = Cache.Get();
if (configuration == null)
{
throw new AbpException(
$"{nameof(ComponentsCachedApplicationConfigurationClient)} should be initialized before using it.");
}
return configuration;
}
}
}

23
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/ComponentsCurrentPrincipalAccessor.cs

@ -1,23 +0,0 @@
using System.Security.Claims;
using Volo.Abp.AspNetCore.Components.UI.Security;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.AspNetCore.Components.UI
{
public class ComponentsCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITransientDependency
{
protected AbpComponentsClaimsCache ClaimsCache { get; }
public ComponentsCurrentPrincipalAccessor(
AbpComponentsClaimsCache claimsCache)
{
ClaimsCache = claimsCache;
}
protected override ClaimsPrincipal GetClaimsPrincipal()
{
return ClaimsCache.Principal;
}
}
}

9
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/ExceptionHandling/UserExceptionInformer.cs

@ -5,7 +5,6 @@ using Volo.Abp.AspNetCore.Components.Messages;
using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http;
using Volo.Abp.Http.Client;
namespace Volo.Abp.AspNetCore.Components.UI.ExceptionHandling
{
@ -41,10 +40,10 @@ namespace Volo.Abp.AspNetCore.Components.UI.ExceptionHandling
protected virtual RemoteServiceErrorInfo GetErrorInfo(UserExceptionInformerContext context)
{
if (context.Exception is AbpRemoteCallException remoteCallException)
{
return remoteCallException.Error;
}
// if (context.Exception is AbpRemoteCallException remoteCallException)
// {
// return remoteCallException.Error;
// }
return ExceptionToErrorInfoConverter.Convert(context.Exception, false);
}

11
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/MultiTenancy/ComponentsCurrentTenantAccessor.cs

@ -1,11 +0,0 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.Components.UI.MultiTenancy
{
[Dependency(ReplaceServices = true)]
public class ComponentsCurrentTenantAccessor : ICurrentTenantAccessor, ISingletonDependency
{
public BasicTenantInfo Current { get; set; }
}
}

70
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/MultiTenancy/ComponentsRemoteTenantStore.cs

@ -1,70 +0,0 @@
using System;
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.MultiTenancy;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.DynamicProxying;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Threading;
namespace Volo.Abp.AspNetCore.Components.UI.MultiTenancy
{
public class ComponentsRemoteTenantStore : ITenantStore, ITransientDependency
{
protected IHttpClientProxy<IAbpTenantAppService> Proxy { get; }
protected ComponentsRemoteTenantStoreCache Cache { get; }
public ComponentsRemoteTenantStore(
IHttpClientProxy<IAbpTenantAppService> proxy,
ComponentsRemoteTenantStoreCache cache)
{
Proxy = proxy;
Cache = cache;
}
public async Task<TenantConfiguration> FindAsync(string name)
{
var cached = Cache.Find(name);
if (cached != null)
{
return cached;
}
var tenant = CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name));
Cache.Set(tenant);
return tenant;
}
public async Task<TenantConfiguration> FindAsync(Guid id)
{
var cached = Cache.Find(id);
if (cached != null)
{
return cached;
}
var tenant = CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id));
Cache.Set(tenant);
return tenant;
}
public TenantConfiguration Find(string name)
{
return AsyncHelper.RunSync(() => FindAsync(name));
}
public TenantConfiguration Find(Guid id)
{
return AsyncHelper.RunSync(() => FindAsync(id));
}
protected virtual TenantConfiguration CreateTenantConfiguration(FindTenantResultDto tenantResultDto)
{
if (!tenantResultDto.Success || tenantResultDto.TenantId == null)
{
return null;
}
return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name);
}
}
}

35
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/MultiTenancy/ComponentsRemoteTenantStoreCache.cs

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.Components.UI.MultiTenancy
{
public class ComponentsRemoteTenantStoreCache : IScopedDependency
{
protected readonly List<TenantConfiguration> CachedTenants = new List<TenantConfiguration>();
public virtual TenantConfiguration Find(string name)
{
return CachedTenants.FirstOrDefault(t => t.Name == name);
}
public virtual TenantConfiguration Find(Guid id)
{
return CachedTenants.FirstOrDefault(t => t.Id == id);
}
public virtual void Set(TenantConfiguration tenant)
{
var existingTenant = Find(tenant.Id);
if (existingTenant != null)
{
existingTenant.Name = tenant.Name;
return;
}
CachedTenants.Add(tenant);
}
}
}

2
framework/src/Volo.Abp.AspNetCore.Components.UI/Volo/Abp/AspNetCore/Components/UI/ApplicationConfigurationCache.cs → framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/ApplicationConfigurationCache.cs

@ -1,7 +1,7 @@
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.UI
namespace Volo.Abp.AspNetCore.Components.WebAssembly
{
public class ApplicationConfigurationCache : ISingletonDependency
{

7
framework/src/Volo.Abp.BlazoriseUI/AbpBlazoriseModule.cs

@ -1,13 +1,16 @@
using Blazorise;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Components;
using Volo.Abp.Application;
using Volo.Abp.AspNetCore.Components.UI;
using Volo.Abp.Authorization;
using Volo.Abp.Modularity;
namespace Volo.Abp.BlazoriseUI
{
[DependsOn(
typeof(AbpAspNetCoreComponentsModule)
typeof(AbpAspNetCoreComponentsUIModule),
typeof(AbpDddApplicationContractsModule),
typeof(AbpAuthorizationModule)
)]
public class AbpBlazoriseUIModule : AbpModule
{

2
framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj

@ -9,6 +9,8 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.UI\Volo.Abp.AspNetCore.Components.UI.csproj" />
<ProjectReference Include="..\Volo.Abp.Authorization\Volo.Abp.Authorization.csproj" />
<ProjectReference Include="..\Volo.Abp.Ddd.Application.Contracts\Volo.Abp.Ddd.Application.Contracts.csproj" />
</ItemGroup>
<ItemGroup>

1
test/BlazorServerSide/AbpBlazorServerDemo/AbpBlazorServerDemo.csproj

@ -14,6 +14,7 @@
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic\Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj" />
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj" />
<ProjectReference Include="..\..\..\framework\src\Volo.Abp.AspNetCore.Components.UI.BasicTheme\Volo.Abp.AspNetCore.Components.UI.BasicTheme.csproj" />
</ItemGroup>

14
test/BlazorServerSide/AbpBlazorServerDemo/AbpBlazorServerDemoModule.cs

@ -5,11 +5,13 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Volo.Abp;
using Volo.Abp.AspNetCore.Components.UI.BasicTheme;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic;
using Volo.Abp.Autofac;
using Volo.Abp.BlazoriseUI;
using Volo.Abp.Modularity;
using Volo.Abp.AspNetCore.Components.UI.Theming.Routing;
namespace AbpBlazorServerDemo
{
@ -17,13 +19,15 @@ namespace AbpBlazorServerDemo
typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMvcModule),
typeof(AbpAspNetCoreMvcUiBasicThemeModule),
typeof(AbpBlazoriseUIModule)
typeof(AbpBlazoriseUIModule),
typeof(AbpAspNetCoreComponentsUiBasicThemeModule)
)]
public class AbpBlazorServerDemoModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
ConfigureBlazorise(context);
ConfigureRouter(context);
context.Services.AddServerSideBlazor();
context.Services.AddSingleton<WeatherForecastService>();
}
@ -34,6 +38,14 @@ namespace AbpBlazorServerDemo
.AddBootstrapProviders()
.AddFontAwesomeIcons();
}
private void ConfigureRouter(ServiceConfigurationContext context)
{
Configure<AbpRouterOptions>(options =>
{
options.AppAssembly = typeof(AbpBlazorServerDemoModule).Assembly;
});
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{

10
test/BlazorServerSide/AbpBlazorServerDemo/App.razor

@ -1,10 +0,0 @@
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

1
test/BlazorServerSide/AbpBlazorServerDemo/Pages/_Host.cshtml

@ -1,4 +1,5 @@
@page "/"
@using Volo.Abp.AspNetCore.Components.UI.BasicTheme.Themes.Basic
@namespace AbpBlazorServerDemo.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{

Loading…
Cancel
Save