@ -0,0 +1,8 @@ |
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; |
|||
|
|||
public class PersistentAccessToken |
|||
{ |
|||
public const string Key = "access_token"; |
|||
|
|||
public string? AccessToken { get; set; } |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Components; |
|||
using Volo.Abp.Http.Client.Authentication; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; |
|||
|
|||
public class PersistentComponentStateAbpAccessTokenProvider : IAbpAccessTokenProvider |
|||
{ |
|||
private string? AccessToken { get; set; } |
|||
|
|||
private readonly PersistentComponentState _persistentComponentState; |
|||
|
|||
public PersistentComponentStateAbpAccessTokenProvider(PersistentComponentState persistentComponentState) |
|||
{ |
|||
_persistentComponentState = persistentComponentState; |
|||
AccessToken = null; |
|||
} |
|||
|
|||
public virtual Task<string?> GetTokenAsync() |
|||
{ |
|||
if (AccessToken != null) |
|||
{ |
|||
return Task.FromResult<string?>(AccessToken); |
|||
} |
|||
|
|||
AccessToken = _persistentComponentState.TryTakeFromJson<PersistentAccessToken>(PersistentAccessToken.Key, out var token) |
|||
? token?.AccessToken |
|||
: null; |
|||
|
|||
return Task.FromResult(AccessToken); |
|||
} |
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Configuration; |
|||
using MyCompanyName.MyProjectName.Localization; |
|||
using MyCompanyName.MyProjectName.MultiTenancy; |
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Identity.Blazor; |
|||
using Volo.Abp.SettingManagement.Blazor.Menus; |
|||
using Volo.Abp.TenantManagement.Blazor.Navigation; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client.Menus; |
|||
|
|||
public class MyProjectNameMenuContributor : IMenuContributor |
|||
{ |
|||
private readonly IConfiguration _configuration; |
|||
|
|||
public MyProjectNameMenuContributor(IConfiguration configuration) |
|||
{ |
|||
_configuration = configuration; |
|||
} |
|||
|
|||
public async Task ConfigureMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
if (context.Menu.Name == StandardMenus.Main) |
|||
{ |
|||
await ConfigureMainMenuAsync(context); |
|||
} |
|||
else if (context.Menu.Name == StandardMenus.User) |
|||
{ |
|||
await ConfigureUserMenuAsync(context); |
|||
} |
|||
} |
|||
|
|||
private Task ConfigureMainMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
var l = context.GetLocalizer<MyProjectNameResource>(); |
|||
|
|||
context.Menu.Items.Insert( |
|||
0, |
|||
new ApplicationMenuItem( |
|||
MyProjectNameMenus.Home, |
|||
l["Menu:Home"], |
|||
"/", |
|||
icon: "fas fa-home" |
|||
) |
|||
); |
|||
|
|||
var administration = context.Menu.GetAdministration(); |
|||
|
|||
if (MultiTenancyConsts.IsEnabled) |
|||
{ |
|||
administration.SetSubItemOrder(TenantManagementMenuNames.GroupName, 1); |
|||
} |
|||
else |
|||
{ |
|||
administration.TryRemoveMenuItem(TenantManagementMenuNames.GroupName); |
|||
} |
|||
|
|||
administration.SetSubItemOrder(IdentityMenuNames.GroupName, 2); |
|||
administration.SetSubItemOrder(SettingManagementMenus.GroupName, 3); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
private Task ConfigureUserMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
var accountStringLocalizer = context.GetLocalizer<AccountResource>(); |
|||
|
|||
var authServerUrl = _configuration["AuthServer:Authority"] ?? ""; |
|||
|
|||
context.Menu.AddItem(new ApplicationMenuItem( |
|||
"Account.Manage", |
|||
accountStringLocalizer["MyAccount"], |
|||
$"{authServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", |
|||
icon: "fa fa-cog", |
|||
order: 1000, |
|||
null).RequireAuthenticated()); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client.Menus; |
|||
|
|||
public class MyProjectNameMenus |
|||
{ |
|||
private const string Prefix = "MyProjectName"; |
|||
public const string Home = Prefix + ".Home"; |
|||
|
|||
//Add your menu items here...
|
|||
|
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData> |
|||
<!-- <TEMPLATE-REMOVE IF-NOT='PWA'> --> |
|||
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest> |
|||
<!-- </TEMPLATE-REMOVE> --> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Blazorise.Bootstrap5" Version="1.4.1" /> |
|||
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.4.1" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.1" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.1" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<!-- <TEMPLATE-REMOVE> --> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Http.Client.IdentityModel.WebAssembly\Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Components.Web.Theming\Volo.Abp.AspNetCore.Components.Web.Theming.csproj" /> |
|||
<!-- </TEMPLATE-REMOVE> --> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme" Version="3.0.*-*" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac.WebAssembly\Volo.Abp.Autofac.WebAssembly.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.Blazor.WebAssembly\Volo.Abp.Identity.Blazor.WebAssembly.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.Blazor.WebAssembly\Volo.Abp.TenantManagement.Blazor.WebAssembly.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.Blazor.WebAssembly\Volo.Abp.SettingManagement.Blazor.WebAssembly.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\MyCompanyName.MyProjectName.HttpApi.Client\MyCompanyName.MyProjectName.HttpApi.Client.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<!-- <TEMPLATE-REMOVE IF-NOT='PWA'> --> |
|||
<ItemGroup> |
|||
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" /> |
|||
</ItemGroup> |
|||
<!-- </TEMPLATE-REMOVE> --> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
using AutoMapper; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client; |
|||
|
|||
public class MyProjectNameBlazorAutoMapperProfile : Profile |
|||
{ |
|||
public MyProjectNameBlazorAutoMapperProfile() |
|||
{ |
|||
//Define your AutoMapper configuration here for the Blazor project.
|
|||
} |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
using System; |
|||
using System.Net.Http; |
|||
using Blazorise.Bootstrap5; |
|||
using Blazorise.Icons.FontAwesome; |
|||
using Microsoft.AspNetCore.Components.Authorization; |
|||
using Microsoft.AspNetCore.Components.WebAssembly.Authentication; |
|||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client.Menus; |
|||
using Volo.Abp.AspNetCore.Components.Web.Theming.Routing; |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme; |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; |
|||
using Volo.Abp.Autofac.WebAssembly; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Http.Client.Authentication; |
|||
using Volo.Abp.Identity.Blazor.WebAssembly; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.SettingManagement.Blazor.WebAssembly; |
|||
using Volo.Abp.TenantManagement.Blazor.WebAssembly; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAutofacWebAssemblyModule), |
|||
typeof(MyProjectNameHttpApiClientModule), |
|||
typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeModule), |
|||
typeof(AbpIdentityBlazorWebAssemblyModule), |
|||
typeof(AbpTenantManagementBlazorWebAssemblyModule), |
|||
typeof(AbpSettingManagementBlazorWebAssemblyModule) |
|||
)] |
|||
public class MyProjectNameBlazorClientModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var environment = context.Services.GetSingletonInstance<IWebAssemblyHostEnvironment>(); |
|||
var builder = context.Services.GetSingletonInstance<WebAssemblyHostBuilder>(); |
|||
|
|||
ConfigureAuthentication(builder); |
|||
ConfigureHttpClient(context, environment); |
|||
ConfigureBlazorise(context); |
|||
ConfigureRouter(context); |
|||
ConfigureMenu(context); |
|||
ConfigureAutoMapper(context); |
|||
} |
|||
|
|||
private void ConfigureRouter(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpRouterOptions>(options => |
|||
{ |
|||
options.AppAssembly = typeof(MyProjectNameBlazorClientModule).Assembly; |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureMenu(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpNavigationOptions>(options => |
|||
{ |
|||
options.MenuContributors.Add(new MyProjectNameMenuContributor(context.Services.GetConfiguration())); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureBlazorise(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services |
|||
.AddBootstrap5Providers() |
|||
.AddFontAwesomeIcons(); |
|||
} |
|||
|
|||
private static void ConfigureAuthentication(WebAssemblyHostBuilder builder) |
|||
{ |
|||
builder.Services.TryAddScoped<SignOutSessionStateManager>(); |
|||
builder.Services.AddBlazorWebAppTieredServices(); |
|||
} |
|||
|
|||
private static void ConfigureHttpClient(ServiceConfigurationContext context, IWebAssemblyHostEnvironment environment) |
|||
{ |
|||
context.Services.AddTransient(sp => new HttpClient |
|||
{ |
|||
BaseAddress = new Uri(environment.BaseAddress) |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureAutoMapper(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddMaps<MyProjectNameBlazorClientModule>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Ui.Branding; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
public class MyProjectNameBrandingProvider : DefaultBrandingProvider |
|||
{ |
|||
public override string AppName => "MyProjectName"; |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using Volo.Abp.Bundling; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client; |
|||
|
|||
/* Add your global styles/scripts here. |
|||
* See https://docs.abp.io/en/abp/latest/UI/Blazor/Global-Scripts-Styles to learn how to use it
|
|||
*/ |
|||
public class MyProjectNameBundleContributor : IBundleContributor |
|||
{ |
|||
public void AddScripts(BundleContext context) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public void AddStyles(BundleContext context) |
|||
{ |
|||
context.Add("main.css", true); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using MyCompanyName.MyProjectName.Localization; |
|||
using Volo.Abp.AspNetCore.Components; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client; |
|||
|
|||
public abstract class MyProjectNameComponentBase : AbpComponentBase |
|||
{ |
|||
protected MyProjectNameComponentBase() |
|||
{ |
|||
LocalizationResource = typeof(MyProjectNameResource); |
|||
} |
|||
} |
|||
@ -0,0 +1,177 @@ |
|||
@page "/" |
|||
@using Volo.Abp.MultiTenancy |
|||
@inherits MyProjectNameComponentBase |
|||
@inject AuthenticationStateProvider AuthenticationStateProvider |
|||
<div class="container"> |
|||
<div class="p-5 text-center"> |
|||
<Badge Color="Color.Success" class="mb-4"> |
|||
<h5 class="m-1"> <i class="fas fa-rocket"></i> Congratulations, <strong>MyProjectName</strong> is successfully running!</h5> |
|||
</Badge> |
|||
|
|||
<h1>Welcome to the Application</h1> |
|||
|
|||
<p class="lead px-lg-5 mx-lg-5">@L["LongWelcomeMessage"]</p> |
|||
|
|||
@if (!CurrentUser.IsAuthenticated) |
|||
{ |
|||
<a class="btn btn-primary" href="/Account/Login"><i class="fa fa-sign-in"></i> @L["Login"]</a> |
|||
} |
|||
</div> |
|||
|
|||
<div class="card"> |
|||
<div class="card-body"> |
|||
<div class="row"> |
|||
<div class="col-md-auto text-center"> |
|||
<img src="https://abp.io/assets/png/mastering-abp-framework.webp" style="max-width: 400px;" class="w-100 mb-5 my-md-3"> |
|||
</div> |
|||
<div class="col-md d-flex align-items-center"> |
|||
<div class="pe-0 pe-md-4"> |
|||
<small class="text-uppercase text-muted">THE OFFICIAL GUIDE</small> |
|||
<h2 class="mb-4">Mastering ABP Framework</h2> |
|||
<p class="mb-4">Written by the creator of the ABP Framework, this book will help you gain a complete understanding of the framework and modern web application development techniques.</p> |
|||
<div class="mb-4"> |
|||
<a href="https://www.amazon.com/gp/product/B097Z2DM8Q/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0" class="btn btn-success mb-1"> |
|||
Buy on Amazon US |
|||
</a> |
|||
<a href="https://www.packtpub.com/product/mastering-abp-framework/9781801079242" class="btn btn-primary mb-1"> |
|||
Buy on PACKT |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="my-3 text-center"> |
|||
<h3>Let's improve your application!</h3> |
|||
<p>Here are some links to help you get started:</p> |
|||
</div> |
|||
|
|||
<div class="card mt-4 mb-5"> |
|||
<div class="card-body"> |
|||
<div class="row text-center justify-content-md-center"> |
|||
<div class="col-lg-4"> |
|||
<div class="p-4"> |
|||
<h5 class="mb-3"><i class="fas fa-book text-secondary d-block my-3 fa-2x"></i> Learn the ABP Framework</h5> |
|||
<p>Explore the compherensive documentation to learn how to build a modern web application.</p> |
|||
<a href="https://docs.abp.io/en/abp/latest?ref=tmpl" target="_blank" class="btn btn-link px-1">See Documents <i class="fas fa-chevron-right"></i></a> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-4 border-start"> |
|||
<div class="p-4"> |
|||
<h5 class="mb-3"><i class="fas fa-cubes text-secondary d-block my-3 fa-2x"></i> Samples</h5> |
|||
<p>See the example projects built with the ABP Framework.</p> |
|||
<a href="https://docs.abp.io/en/abp/latest/Samples/Index?ref=tmpl" target="_blank" class="btn btn-link px-1">All samples <i class="fas fa-chevron-right"></i></a> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-4 border-start"> |
|||
<div class="p-4"> |
|||
<h5 class="mb-3"><i class="fas fa-users text-secondary d-block my-3 fa-2x"></i> ABP Community</h5> |
|||
<p>Get involved with a vibrant community and become a contributor.</p> |
|||
<a href="https://community.abp.io/" target="_blank" class="btn btn-link px-1">Community <i class="fas fa-chevron-right"></i></a> |
|||
<a href="https://docs.abp.io/en/abp/latest/Contribution/Index?ref=tmpl" target="_blank" class="btn btn-link px-1">Contribute <i class="fas fa-chevron-right"></i></a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="row text-center mt-lg-3 justify-content-md-center"> |
|||
<div class="col-lg-4"> |
|||
<div class="p-4"> |
|||
<h5 class="mb-3"><i class="fas fa-pen-nib text-secondary d-block my-3 fa-2x"></i> ABP Blog</h5> |
|||
<p>Take a look at our recently published articles.</p> |
|||
<a href="https://blog.abp.io/abp?ref=tmpl" target="_blank" class="btn btn-link px-1">See Blog <i class="fas fa-chevron-right"></i></a> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-4 border-start"> |
|||
<div class="p-4"> |
|||
<h5 class="mb-3"><i class="fab fa-github text-secondary d-block my-3 fa-2x"></i> Github</h5> |
|||
<p>Do you love the ABP Framework? Please <strong>give a star</strong> to support it!</p> |
|||
|
|||
<a href="https://github.com/abpframework/abp/" target="_blank" class="btn btn-link px-1">See Open Source Framework <i class="fas fa-chevron-right"></i></a> |
|||
|
|||
</div> |
|||
</div> |
|||
<div class="col-lg-4 border-start"> |
|||
<div class="p-4"> |
|||
<h5 class="mb-3"><i class="fab fa-stack-overflow text-secondary d-block my-3 fa-2x"></i> Stackoverflow</h5> |
|||
<p>See answers to previously asked questions or ask a new one.</p> |
|||
<a href="https://stackoverflow.com/questions/tagged/abp" target="_blank" class="btn btn-link px-1">Questions <i class="fas fa-chevron-right"></i></a> |
|||
<a href="https://stackoverflow.com/questions/ask" target="_blank" class="btn btn-link px-1">Ask a Question <i class="fas fa-chevron-right"></i></a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="mt-5 my-3 text-center"> |
|||
<h3>Meet the ABP Commercial</h3> |
|||
<p>A Complete Web Application Platform Built on the ABP Framework</p> |
|||
</div> |
|||
|
|||
<div class="card mt-4 mb-5"> |
|||
<div class="card-body"> |
|||
<p class="px-lg-5 mx-lg-5 py-3 text-center"> |
|||
<a href="https://commercial.abp.io/" target="_blank">ABP Commercial</a> is a platform based on the open source ABP framework. It provides pre-built application modules, |
|||
rapid application development tooling, professional UI themes, premium support and more. |
|||
</p> |
|||
|
|||
<div class="row text-center justify-content-md-center"> |
|||
<div class="col-lg-2"> |
|||
<div class="p-3"> |
|||
<h6> |
|||
<i class="fas fa-plus d-block mb-3 fa- 2x text-secondary"></i> Startup Templates |
|||
<a href="https://commercial.abp.io/startup-templates?ref=tmpl" target="_blank" class="d-block mt-2 btn btn-sm btn-link">Details <i class="fas fa-chevron-right"></i></a> |
|||
</h6> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-2 border-start"> |
|||
<div class="p-3"> |
|||
<h6> |
|||
<i class="fas fa-plus d-block mb-3 fa- 2x text-secondary"></i> Application Modules |
|||
<a href="https://commercial.abp.io/modules?ref=tmpl" target="_blank" class="d-block mt-2 btn btn-sm btn-link">Details <i class="fas fa-chevron-right"></i></a> |
|||
</h6> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-2 border-start"> |
|||
<div class="p-3"> |
|||
<h6> |
|||
<i class="fas fa-plus d-block mb-3 fa- 2x text-secondary"></i> Developer<br />Tools |
|||
<a href="https://commercial.abp.io/tools?ref=tmpl" target="_blank" class="d-block mt-2 btn btn-sm btn-link">Details <i class="fas fa-chevron-right"></i></a> |
|||
</h6> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-2 border-start"> |
|||
<div class="p-3"> |
|||
<h6> |
|||
<i class="fas fa-plus d-block mb-3 fa- 2x text-secondary"></i> UI<br /> Themes |
|||
<a href="https://commercial.abp.io/themes?ref=tmpl" target="_blank" class="d-block mt-2 btn btn-sm btn-link">Details <i class="fas fa-chevron-right"></i></a> |
|||
</h6> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-2 border-start"> |
|||
<div class="p-3"> |
|||
<h6> |
|||
<i class="fas fa-plus d-block mb-3 fa- 2x text-secondary"></i> Premium Support |
|||
<a href="https://support.abp.io/QA/Questions?ref=tmpl" target="_blank" class="d-block mt-2 btn btn-sm btn-link">Details <i class="fas fa-chevron-right"></i></a> |
|||
</h6> |
|||
</div> |
|||
</div> |
|||
<div class="col-lg-2 border-start"> |
|||
<div class="p-3"> |
|||
<h6> |
|||
<i class="fas fa-plus d-block mb-3 fa- 2x text-secondary"></i> Additional Services |
|||
<a href="https://commercial.abp.io/additional-services?ref=tmpl" target="_blank" class="d-block mt-2 btn btn-sm btn-link">Details <i class="fas fa-chevron-right"></i></a> |
|||
</h6> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="mb-5 text-center"> |
|||
<p class="align-middle"> |
|||
<a href="https://twitter.com/abpframework" target="_blank" class="mx-2"><i class="fab fa-twitter"></i><span class="text-secondary"> Abp Framework</span></a> |
|||
<a href="https://twitter.com/abpcommercial" target="_blank" class="mx-2"><i class="fab fa-twitter"></i><span class="text-secondary"> Abp Commercial</span></a> |
|||
<a href="https://github.com/abpframework/abp" target="_blank" class="mx-2"><i class="fab fa-github"></i><span class="text-secondary"> abpframework</span></a> |
|||
</p> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,6 @@ |
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client.Pages; |
|||
|
|||
public partial class Index |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1 @@ |
|||
/* Write here your styles for the Index page */ |
|||
@ -0,0 +1,22 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client; |
|||
|
|||
public class Program |
|||
{ |
|||
public async static Task Main(string[] args) |
|||
{ |
|||
var builder = WebAssemblyHostBuilder.CreateDefault(args); |
|||
var application = await builder.AddApplicationAsync<MyProjectNameBlazorClientModule>(options => |
|||
{ |
|||
options.UseAutofac(); |
|||
}); |
|||
|
|||
var host = builder.Build(); |
|||
|
|||
await application.InitializeApplicationAsync(host.Services); |
|||
|
|||
await host.RunAsync(); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
@using Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite |
|||
@using Volo.Abp.AspNetCore.Components.Web.Theming.Routing |
|||
@using Microsoft.Extensions.Options |
|||
@inject IOptions<AbpRouterOptions> RouterOptions |
|||
<Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="RouterOptions.Value.AdditionalAssemblies"> |
|||
<Found Context="routeData"> |
|||
<AuthorizeRouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)"> |
|||
<NotAuthorized> |
|||
<RedirectToLogin /> |
|||
</NotAuthorized> |
|||
</AuthorizeRouteView> |
|||
<FocusOnNavigate RouteData="routeData" Selector="h1" /> |
|||
</Found> |
|||
</Router> |
|||
@ -0,0 +1,15 @@ |
|||
@using System.Net.Http |
|||
@using Microsoft.AspNetCore.Authorization |
|||
@using Microsoft.AspNetCore.Components.Authorization |
|||
@using Microsoft.AspNetCore.Components.Forms |
|||
@using Microsoft.AspNetCore.Components.Routing |
|||
@using Microsoft.AspNetCore.Components.Web |
|||
@using Microsoft.AspNetCore.Components.WebAssembly.Http |
|||
@using static Microsoft.AspNetCore.Components.Web.RenderMode |
|||
@using Microsoft.JSInterop |
|||
@using Volo.Abp.AspNetCore.Components.Web |
|||
@using MyCompanyName.MyProjectName.Blazor |
|||
@using Blazorise |
|||
@using Blazorise.DataGrid |
|||
@using Volo.Abp.BlazoriseUI |
|||
@using Volo.Abp.BlazoriseUI.Components |
|||
@ -0,0 +1,3 @@ |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
{ |
|||
"App": { |
|||
"SelfUrl": "https://localhost:44309" |
|||
}, |
|||
"AuthServer": { |
|||
"Authority": "https://localhost:44301" |
|||
}, |
|||
"RemoteServices": { |
|||
"Default": { |
|||
"BaseUrl": "https://localhost:44300" |
|||
} |
|||
}, |
|||
"AbpCli": { |
|||
"Bundle": { |
|||
"Mode": "BundleAndMinify", /* Options: None, Bundle, BundleAndMinify */ |
|||
"Name": "global", |
|||
"IsBlazorWebApp": true, |
|||
"Parameters": { |
|||
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
@ -0,0 +1,57 @@ |
|||
/* Global styles for the MyProjectName application */ |
|||
|
|||
/* <TEMPLATE-REMOVE IF-NOT='LEPTONX'> */ |
|||
:root .lpx-brand-logo { |
|||
--lpx-logo: url('/images/logo/leptonx/logo-light.png'); |
|||
--lpx-logo-icon: url('/images/logo/leptonx/logo-light-thumbnail.png'); |
|||
} |
|||
/* </TEMPLATE-REMOVE> */ |
|||
|
|||
.spinner { |
|||
width: 40px; |
|||
height: 40px; |
|||
display: block; |
|||
position: fixed; |
|||
top: calc( 50% - ( 40px / 2) ); |
|||
right: calc( 50% - ( 40px / 2) ); |
|||
} |
|||
|
|||
.double-bounce1, .double-bounce2 { |
|||
width: 100%; |
|||
height: 100%; |
|||
border-radius: 50%; |
|||
background-color: #333; |
|||
opacity: 0.6; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
-webkit-animation: sk-bounce 2.0s infinite ease-in-out; |
|||
animation: sk-bounce 2.0s infinite ease-in-out; |
|||
} |
|||
|
|||
.double-bounce2 { |
|||
-webkit-animation-delay: -1.0s; |
|||
animation-delay: -1.0s; |
|||
} |
|||
|
|||
@-webkit-keyframes sk-bounce { |
|||
0%, 100% { |
|||
-webkit-transform: scale(0.0) |
|||
} |
|||
|
|||
50% { |
|||
-webkit-transform: scale(1.0) |
|||
} |
|||
} |
|||
|
|||
@keyframes sk-bounce { |
|||
0%, 100% { |
|||
transform: scale(0.0); |
|||
-webkit-transform: scale(0.0); |
|||
} |
|||
|
|||
50% { |
|||
transform: scale(1.0); |
|||
-webkit-transform: scale(1.0); |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
{ |
|||
"name": "MyProjectName", |
|||
"short_name": "MyCompanyName.MyProjectName", |
|||
"start_url": "./", |
|||
"display": "standalone", |
|||
"background_color": "#ffffff", |
|||
"theme_color": "#03173d", |
|||
"prefer_related_applications": false, |
|||
"icons": [ |
|||
{ |
|||
"src": "icon-512.png", |
|||
"type": "image/png", |
|||
"sizes": "512x512" |
|||
}, |
|||
{ |
|||
"src": "icon-192.png", |
|||
"type": "image/png", |
|||
"sizes": "192x192" |
|||
} |
|||
] |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
// In development, always fetch from the network and do not enable offline support.
|
|||
// This is because caching would make development more difficult (changes would not
|
|||
// be reflected on the first load after each change).
|
|||
self.addEventListener('fetch', () => { }); |
|||
@ -0,0 +1,48 @@ |
|||
// Caution! Be sure you understand the caveats before publishing an application with
|
|||
// offline support. See https://aka.ms/blazor-offline-considerations
|
|||
|
|||
self.importScripts('./service-worker-assets.js'); |
|||
self.addEventListener('install', event => event.waitUntil(onInstall(event))); |
|||
self.addEventListener('activate', event => event.waitUntil(onActivate(event))); |
|||
self.addEventListener('fetch', event => event.respondWith(onFetch(event))); |
|||
|
|||
const cacheNamePrefix = 'offline-cache-'; |
|||
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; |
|||
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ]; |
|||
const offlineAssetsExclude = [ /^service-worker\.js$/ ]; |
|||
|
|||
async function onInstall(event) { |
|||
console.info('Service worker: Install'); |
|||
|
|||
// Fetch and cache all matching items from the assets manifest
|
|||
const assetsRequests = self.assetsManifest.assets |
|||
.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url))) |
|||
.filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url))) |
|||
.map(asset => new Request(asset.url, { integrity: asset.hash, cache: 'no-cache' })); |
|||
await caches.open(cacheName).then(cache => cache.addAll(assetsRequests)); |
|||
} |
|||
|
|||
async function onActivate(event) { |
|||
console.info('Service worker: Activate'); |
|||
|
|||
// Delete unused caches
|
|||
const cacheKeys = await caches.keys(); |
|||
await Promise.all(cacheKeys |
|||
.filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName) |
|||
.map(key => caches.delete(key))); |
|||
} |
|||
|
|||
async function onFetch(event) { |
|||
let cachedResponse = null; |
|||
if (event.request.method === 'GET') { |
|||
// For all navigation requests, try to serve index.html from cache
|
|||
// If you need some URLs to be server-rendered, edit the following check to exclude those URLs
|
|||
const shouldServeIndexHtml = event.request.mode === 'navigate'; |
|||
|
|||
const request = shouldServeIndexHtml ? 'index.html' : event.request; |
|||
const cache = await caches.open(cacheName); |
|||
cachedResponse = await cache.match(request); |
|||
} |
|||
|
|||
return cachedResponse || fetch(event.request); |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
@using Volo.Abp.Localization |
|||
@using System.Globalization |
|||
@using Microsoft.AspNetCore.Authentication |
|||
@using Microsoft.AspNetCore.Http |
|||
@using Microsoft.Extensions.Hosting |
|||
@using Volo.Abp.AspNetCore.Components.Server.Theming.Bundling |
|||
@using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme.Bundling |
|||
@using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp |
|||
@inject IHostEnvironment Env |
|||
@{ |
|||
var rtl = CultureHelper.IsRtl ? "rtl" : string.Empty; |
|||
} |
|||
|
|||
<!DOCTYPE html> |
|||
<html lang="@CultureInfo.CurrentCulture.Name" dir="@rtl"> |
|||
|
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<title>MyCompanyName.MyProjectName.Blazor.Server</title> |
|||
<base href="/" /> |
|||
|
|||
<AbpStyles BundleName="@BlazorLeptonXLiteThemeBundles.Styles.Global" /> |
|||
|
|||
<HeadOutlet @rendermode="InteractiveAuto" /> |
|||
|
|||
</head> |
|||
<body> |
|||
|
|||
<Routes @rendermode="InteractiveAuto" /> |
|||
|
|||
<AbpScripts BundleName="@BlazorLeptonXLiteThemeBundles.Scripts.Global" /> |
|||
|
|||
<div id="blazor-error-ui"> |
|||
@if (Env.IsDevelopment()) |
|||
{ |
|||
<text>An unhandled exception has occurred. See browser dev tools for details.</text> |
|||
} |
|||
else if (Env.IsStaging() || Env.IsProduction()) |
|||
{ |
|||
<text>An error has occurred. This application may no longer respond until reloaded.</text> |
|||
} |
|||
<a href="" class="reload">Reload</a> |
|||
<a class="dismiss">🗙</a> |
|||
</div> |
|||
|
|||
</body> |
|||
</html> |
|||
|
|||
@code{ |
|||
[CascadingParameter] |
|||
private HttpContext HttpContext { get; set; } = default!; |
|||
|
|||
[Inject] |
|||
private PersistentComponentState PersistentComponentState { get; set; } |
|||
|
|||
private string? Token { get; set; } = default!; |
|||
|
|||
protected override async Task OnInitializedAsync() |
|||
{ |
|||
if (HttpContext.User?.Identity?.IsAuthenticated == true) |
|||
{ |
|||
Token = await HttpContext.GetTokenAsync("access_token"); |
|||
} |
|||
|
|||
PersistentComponentState.RegisterOnPersisting(OnPersistingAsync, RenderMode.InteractiveWebAssembly); |
|||
} |
|||
|
|||
async Task OnPersistingAsync() |
|||
{ |
|||
if (!Token.IsNullOrWhiteSpace()) |
|||
{ |
|||
PersistentComponentState.PersistAsJson(PersistentAccessToken.Key, new PersistentAccessToken |
|||
{ |
|||
AccessToken = Token |
|||
}); |
|||
} |
|||
|
|||
await Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@using MyCompanyName.MyProjectName.Localization |
|||
@inject IHtmlLocalizer<MyProjectNameResource> L |
|||
<a class="nav-link" role="button" href="~/Account/Login">@L["Login"]</a> |
|||
@ -0,0 +1,12 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Components.Toolbar.LoginLink; |
|||
|
|||
public class LoginLinkViewComponent : AbpViewComponent |
|||
{ |
|||
public virtual IViewComponentResult Invoke() |
|||
{ |
|||
return View("~/Components/Toolbar/LoginLink/Default.cshtml"); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.Authentication; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Controllers; |
|||
|
|||
public class AccountController : ChallengeAccountController |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Configuration; |
|||
using MyCompanyName.MyProjectName.Localization; |
|||
using MyCompanyName.MyProjectName.MultiTenancy; |
|||
using Volo.Abp.Account.Localization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Identity.Blazor; |
|||
using Volo.Abp.SettingManagement.Blazor.Menus; |
|||
using Volo.Abp.TenantManagement.Blazor.Navigation; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Menus; |
|||
|
|||
public class MyProjectNameMenuContributor : IMenuContributor |
|||
{ |
|||
private readonly IConfiguration _configuration; |
|||
|
|||
public MyProjectNameMenuContributor(IConfiguration configuration) |
|||
{ |
|||
_configuration = configuration; |
|||
} |
|||
|
|||
public async Task ConfigureMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
if (context.Menu.Name == StandardMenus.Main) |
|||
{ |
|||
await ConfigureMainMenuAsync(context); |
|||
} |
|||
else if (context.Menu.Name == StandardMenus.User) |
|||
{ |
|||
await ConfigureUserMenuAsync(context); |
|||
} |
|||
} |
|||
|
|||
private Task ConfigureMainMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
var administration = context.Menu.GetAdministration(); |
|||
var l = context.GetLocalizer<MyProjectNameResource>(); |
|||
|
|||
context.Menu.Items.Insert( |
|||
0, |
|||
new ApplicationMenuItem( |
|||
MyProjectNameMenus.Home, |
|||
l["Menu:Home"], |
|||
"/", |
|||
icon: "fas fa-home", |
|||
order: 0 |
|||
) |
|||
); |
|||
|
|||
if (MultiTenancyConsts.IsEnabled) |
|||
{ |
|||
administration.SetSubItemOrder(TenantManagementMenuNames.GroupName, 1); |
|||
} |
|||
else |
|||
{ |
|||
administration.TryRemoveMenuItem(TenantManagementMenuNames.GroupName); |
|||
} |
|||
|
|||
administration.SetSubItemOrder(IdentityMenuNames.GroupName, 2); |
|||
administration.SetSubItemOrder(SettingManagementMenus.GroupName, 3); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
private Task ConfigureUserMenuAsync(MenuConfigurationContext context) |
|||
{ |
|||
var l = context.GetLocalizer<MyProjectNameResource>(); |
|||
var accountStringLocalizer = context.GetLocalizer<AccountResource>(); |
|||
var authServerUrl = _configuration["AuthServer:Authority"] ?? ""; |
|||
|
|||
context.Menu.AddItem(new ApplicationMenuItem("Account.Manage", accountStringLocalizer["MyAccount"], |
|||
$"{authServerUrl.EnsureEndsWith('/')}Account/Manage?returnUrl={_configuration["App:SelfUrl"]}", icon: "fa fa-cog", order: 1000, null, "_blank").RequireAuthenticated()); |
|||
context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "~/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000).RequireAuthenticated()); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Menus; |
|||
|
|||
public class MyProjectNameMenus |
|||
{ |
|||
private const string Prefix = "MyProjectName"; |
|||
public const string Home = Prefix + ".Home"; |
|||
|
|||
//Add your menu items here...
|
|||
|
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Components.Toolbar.LoginLink; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Menus; |
|||
|
|||
public class MyProjectNameToolbarContributor : IToolbarContributor |
|||
{ |
|||
public virtual Task ConfigureToolbarAsync(IToolbarConfigurationContext context) |
|||
{ |
|||
if (context.Toolbar.Name != StandardToolbars.Main) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
if (!context.ServiceProvider.GetRequiredService<ICurrentUser>().IsAuthenticated) |
|||
{ |
|||
context.Toolbar.Items.Add(new ToolbarItem(typeof(LoginLinkViewComponent))); |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -0,0 +1,70 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> |
|||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> |
|||
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> |
|||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish> |
|||
<PreserveCompilationReferences>true</PreserveCompilationReferences> |
|||
<UserSecretsId>MyCompanyName.MyProjectName-4681b4fd-151f-4221-84a4-929d86723e4c</UserSecretsId> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.1" /> |
|||
<PackageReference Include="Blazorise.Bootstrap5" Version="1.4.1" /> |
|||
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.4.1" /> |
|||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.0" /> |
|||
<PackageReference Include="DistributedLock.Redis" Version="1.0.2" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<!-- <TEMPLATE-REMOVE> --> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Components.Server.Theming\Volo.Abp.AspNetCore.Components.Server.Theming.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Components.Web.Theming\Volo.Abp.AspNetCore.Components.Web.Theming.csproj" /> |
|||
<!-- </TEMPLATE-REMOVE> --> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme" Version="3.0.*-*" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="3.0.*-*" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client\MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client.csproj" /> |
|||
<ProjectReference Include="..\MyCompanyName.MyProjectName.HttpApi.Client\MyCompanyName.MyProjectName.HttpApi.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Caching.StackExchangeRedis\Volo.Abp.Caching.StackExchangeRedis.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.DistributedLocking\Volo.Abp.DistributedLocking.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc.Client\Volo.Abp.AspNetCore.Mvc.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Authentication.OpenIdConnect\Volo.Abp.AspNetCore.Authentication.OpenIdConnect.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Http.Client.IdentityModel.Web\Volo.Abp.Http.Client.IdentityModel.Web.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Swashbuckle\Volo.Abp.Swashbuckle.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Serilog\Volo.Abp.AspNetCore.Serilog.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.Blazor.Server\Volo.Abp.Identity.Blazor.Server.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.Blazor.Server\Volo.Abp.TenantManagement.Blazor.Server.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.Blazor.Server\Volo.Abp.SettingManagement.Blazor.Server.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="Logs\**" /> |
|||
<Content Remove="Logs\**" /> |
|||
<EmbeddedResource Remove="Logs\**" /> |
|||
<None Remove="Logs\**" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Update="Pages\**\*.js"> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</None> |
|||
<None Update="Pages\**\*.css"> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</None> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,394 @@ |
|||
using System; |
|||
using System.IO; |
|||
using Blazorise.Bootstrap5; |
|||
using Blazorise.Icons.FontAwesome; |
|||
using Medallion.Threading; |
|||
using Medallion.Threading.Redis; |
|||
using Microsoft.AspNetCore.Authentication.Cookies; |
|||
using Microsoft.AspNetCore.Authentication.OpenIdConnect; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage; |
|||
using Microsoft.AspNetCore.DataProtection; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.IdentityModel.Protocols.OpenIdConnect; |
|||
using Microsoft.OpenApi.Models; |
|||
using MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client; |
|||
using MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Components; |
|||
using MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Menus; |
|||
using MyCompanyName.MyProjectName.Localization; |
|||
using MyCompanyName.MyProjectName.MultiTenancy; |
|||
using StackExchange.Redis; |
|||
using Volo.Abp; |
|||
using Volo.Abp.AspNetCore.Authentication.OpenIdConnect; |
|||
using Volo.Abp.AspNetCore.Components.Server; |
|||
using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme; |
|||
using Volo.Abp.AspNetCore.Components.Server.LeptonXLiteTheme.Bundling; |
|||
using Volo.Abp.AspNetCore.Components.Web.Theming.Routing; |
|||
using Volo.Abp.AspNetCore.Mvc.Client; |
|||
using Volo.Abp.AspNetCore.Mvc.Localization; |
|||
using Volo.Abp.AspNetCore.Mvc.UI; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; |
|||
using Volo.Abp.AspNetCore.Serilog; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.Caching.StackExchangeRedis; |
|||
using Volo.Abp.DistributedLocking; |
|||
using Volo.Abp.Http.Client.IdentityModel.Web; |
|||
using Volo.Abp.Identity.Blazor.Server; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Security.Claims; |
|||
using Volo.Abp.SettingManagement.Blazor.Server; |
|||
using Volo.Abp.Swashbuckle; |
|||
using Volo.Abp.TenantManagement.Blazor.Server; |
|||
using Volo.Abp.UI; |
|||
using Volo.Abp.UI.Navigation; |
|||
using Volo.Abp.UI.Navigation.Urls; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered; |
|||
|
|||
[DependsOn( |
|||
typeof(MyProjectNameHttpApiClientModule), |
|||
typeof(AbpCachingStackExchangeRedisModule), |
|||
typeof(AbpDistributedLockingModule), |
|||
typeof(AbpAspNetCoreMvcClientModule), |
|||
typeof(AbpAspNetCoreAuthenticationOpenIdConnectModule), |
|||
typeof(AbpHttpClientIdentityModelWebModule), |
|||
typeof(AbpAspNetCoreComponentsServerLeptonXLiteThemeModule), |
|||
typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpSwashbuckleModule), |
|||
typeof(AbpAspNetCoreSerilogModule), |
|||
typeof(AbpIdentityBlazorServerModule), |
|||
typeof(AbpTenantManagementBlazorServerModule), |
|||
typeof(AbpSettingManagementBlazorServerModule) |
|||
)] |
|||
public class MyProjectNameBlazorModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
|||
{ |
|||
options.AddAssemblyResource( |
|||
typeof(MyProjectNameResource), |
|||
typeof(MyProjectNameDomainSharedModule).Assembly, |
|||
typeof(MyProjectNameApplicationContractsModule).Assembly, |
|||
typeof(MyProjectNameBlazorModule).Assembly |
|||
); |
|||
}); |
|||
|
|||
PreConfigure<AbpAspNetCoreComponentsWebOptions>(options => |
|||
{ |
|||
options.IsBlazorWebApp = true; |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
// Add services to the container.
|
|||
context.Services.AddRazorComponents() |
|||
.AddInteractiveServerComponents() |
|||
.AddInteractiveWebAssemblyComponents(); |
|||
|
|||
ConfigureUrls(configuration); |
|||
ConfigureCache(); |
|||
ConfigureBundles(); |
|||
ConfigureMultiTenancy(); |
|||
ConfigureAuthentication(context, configuration); |
|||
ConfigureAutoMapper(); |
|||
ConfigureVirtualFileSystem(hostingEnvironment); |
|||
ConfigureBlazorise(context); |
|||
ConfigureRouter(context); |
|||
ConfigureMenu(configuration); |
|||
ConfigureDataProtection(context, configuration, hostingEnvironment); |
|||
ConfigureDistributedLocking(context, configuration); |
|||
ConfigureSwaggerServices(context.Services); |
|||
} |
|||
|
|||
private void ConfigureUrls(IConfiguration configuration) |
|||
{ |
|||
Configure<AppUrlOptions>(options => |
|||
{ |
|||
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureCache() |
|||
{ |
|||
Configure<AbpDistributedCacheOptions>(options => |
|||
{ |
|||
options.KeyPrefix = "MyProjectName:"; |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureBundles() |
|||
{ |
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
// MVC UI
|
|||
options.StyleBundles.Configure( |
|||
LeptonXLiteThemeBundles.Styles.Global, |
|||
bundle => |
|||
{ |
|||
bundle.AddFiles("/global-styles.css"); |
|||
} |
|||
); |
|||
|
|||
//BLAZOR UI
|
|||
options.StyleBundles.Configure( |
|||
BlazorLeptonXLiteThemeBundles.Styles.Global, |
|||
bundle => |
|||
{ |
|||
bundle.AddFiles("/blazor-global-styles.css"); |
|||
//You can remove the following line if you don't use Blazor CSS isolation for components
|
|||
bundle.AddFiles("/MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client.styles.css"); |
|||
} |
|||
); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureMultiTenancy() |
|||
{ |
|||
Configure<AbpMultiTenancyOptions>(options => |
|||
{ |
|||
options.IsEnabled = MultiTenancyConsts.IsEnabled; |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration) |
|||
{ |
|||
context.Services.TryAddScoped<ProtectedLocalStorage>(); |
|||
context.Services.AddAuthentication(options => |
|||
{ |
|||
options.DefaultScheme = "Cookies"; |
|||
options.DefaultChallengeScheme = "oidc"; |
|||
}) |
|||
.AddCookie("Cookies", options => |
|||
{ |
|||
options.ExpireTimeSpan = TimeSpan.FromDays(365); |
|||
options.IntrospectAccessToken(); |
|||
}) |
|||
.AddAbpOpenIdConnect("oidc", options => |
|||
{ |
|||
options.Authority = configuration["AuthServer:Authority"]; |
|||
options.RequireHttpsMetadata = configuration.GetValue<bool>("AuthServer:RequireHttpsMetadata"); |
|||
options.ResponseType = OpenIdConnectResponseType.CodeIdToken; |
|||
|
|||
options.ClientId = configuration["AuthServer:ClientId"]; |
|||
options.ClientSecret = configuration["AuthServer:ClientSecret"]; |
|||
|
|||
options.SaveTokens = true; |
|||
options.GetClaimsFromUserInfoEndpoint = true; |
|||
|
|||
options.Scope.Add("roles"); |
|||
options.Scope.Add("email"); |
|||
options.Scope.Add("phone"); |
|||
options.Scope.Add("MyProjectName"); |
|||
}); |
|||
/* |
|||
* This configuration is used when the AuthServer is running on the internal network such as docker or k8s. |
|||
* Configuring the redirecting URLs for internal network and the web |
|||
* The login and the logout URLs are configured to redirect to the AuthServer real DNS for browser. |
|||
* The token acquired and validated from the the internal network AuthServer URL. |
|||
*/ |
|||
if (configuration.GetValue<bool>("AuthServer:IsContainerized")) |
|||
{ |
|||
context.Services.Configure<OpenIdConnectOptions>("oidc", options => |
|||
{ |
|||
options.TokenValidationParameters.ValidIssuers = new[] |
|||
{ |
|||
configuration["AuthServer:MetaAddress"]!.EnsureEndsWith('/'), |
|||
configuration["AuthServer:Authority"]!.EnsureEndsWith('/') |
|||
}; |
|||
|
|||
options.MetadataAddress = configuration["AuthServer:MetaAddress"]!.EnsureEndsWith('/') + |
|||
".well-known/openid-configuration"; |
|||
|
|||
var previousOnRedirectToIdentityProvider = options.Events.OnRedirectToIdentityProvider; |
|||
options.Events.OnRedirectToIdentityProvider = async ctx => |
|||
{ |
|||
// Intercept the redirection so the browser navigates to the right URL in your host
|
|||
ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"]!.EnsureEndsWith('/') + "connect/authorize"; |
|||
|
|||
if (previousOnRedirectToIdentityProvider != null) |
|||
{ |
|||
await previousOnRedirectToIdentityProvider(ctx); |
|||
} |
|||
}; |
|||
var previousOnRedirectToIdentityProviderForSignOut = options.Events.OnRedirectToIdentityProviderForSignOut; |
|||
options.Events.OnRedirectToIdentityProviderForSignOut = async ctx => |
|||
{ |
|||
// Intercept the redirection for signout so the browser navigates to the right URL in your host
|
|||
ctx.ProtocolMessage.IssuerAddress = configuration["AuthServer:Authority"]!.EnsureEndsWith('/') + "connect/logout"; |
|||
|
|||
if (previousOnRedirectToIdentityProviderForSignOut != null) |
|||
{ |
|||
await previousOnRedirectToIdentityProviderForSignOut(ctx); |
|||
} |
|||
}; |
|||
}); |
|||
} |
|||
|
|||
context.Services.Configure<AbpClaimsPrincipalFactoryOptions>(options => |
|||
{ |
|||
options.IsDynamicClaimsEnabled = true; |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureVirtualFileSystem(IWebHostEnvironment hostingEnvironment) |
|||
{ |
|||
if (hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
//<TEMPLATE-REMOVE>
|
|||
options.FileSets.ReplaceEmbeddedByPhysical<AbpUiModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); |
|||
options.FileSets.ReplaceEmbeddedByPhysical<AbpAspNetCoreMvcUiModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); |
|||
options.FileSets.ReplaceEmbeddedByPhysical<AbpAspNetCoreMvcUiBootstrapModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.Bootstrap", Path.DirectorySeparatorChar))); |
|||
//options.FileSets.ReplaceEmbeddedByPhysical<AbpAspNetCoreMvcUiThemeSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared", Path.DirectorySeparatorChar)));
|
|||
options.FileSets.ReplaceEmbeddedByPhysical<AbpAspNetCoreMvcUiMultiTenancyModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy", Path.DirectorySeparatorChar))); |
|||
//options.FileSets.ReplaceEmbeddedByPhysical<AbpPermissionManagementWebModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}modules{0}permission-management{0}src{0}Volo.Abp.PermissionManagement.Web", Path.DirectorySeparatorChar)));
|
|||
//options.FileSets.ReplaceEmbeddedByPhysical<AbpFeatureManagementWebModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}modules{0}feature-management{0}src{0}Volo.Abp.FeatureManagement.Web", Path.DirectorySeparatorChar)));
|
|||
//options.FileSets.ReplaceEmbeddedByPhysical<AbpIdentityWebModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}modules{0}identity{0}src{0}Volo.Abp.Identity.Web", Path.DirectorySeparatorChar)));
|
|||
//options.FileSets.ReplaceEmbeddedByPhysical<AbpTenantManagementWebModule>(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}..{0}modules{0}tenant-management{0}src{0}Volo.Abp.TenantManagement.Web", Path.DirectorySeparatorChar)));
|
|||
//</TEMPLATE-REMOVE>
|
|||
options.FileSets.ReplaceEmbeddedByPhysical<MyProjectNameDomainSharedModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}MyCompanyName.MyProjectName.Domain.Shared")); |
|||
options.FileSets.ReplaceEmbeddedByPhysical<MyProjectNameApplicationContractsModule>(Path.Combine(hostingEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}MyCompanyName.MyProjectName.Application.Contracts")); |
|||
options.FileSets.ReplaceEmbeddedByPhysical<MyProjectNameBlazorModule>(hostingEnvironment.ContentRootPath); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
private void ConfigureBlazorise(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services |
|||
.AddBootstrap5Providers() |
|||
.AddFontAwesomeIcons(); |
|||
} |
|||
|
|||
private void ConfigureMenu(IConfiguration configuration) |
|||
{ |
|||
Configure<AbpNavigationOptions>(options => |
|||
{ |
|||
options.MenuContributors.Add(new MyProjectNameMenuContributor(configuration)); |
|||
}); |
|||
|
|||
Configure<AbpToolbarOptions>(options => |
|||
{ |
|||
options.Contributors.Add(new MyProjectNameToolbarContributor()); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureRouter(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpRouterOptions>(options => |
|||
{ |
|||
options.AppAssembly = typeof(MyProjectNameBlazorModule).Assembly; |
|||
options.AdditionalAssemblies.Add(typeof(MyProjectNameBlazorClientModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureAutoMapper() |
|||
{ |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddMaps<MyProjectNameBlazorModule>(); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureSwaggerServices(IServiceCollection services) |
|||
{ |
|||
services.AddAbpSwaggerGen( |
|||
options => |
|||
{ |
|||
options.SwaggerDoc("v1", new OpenApiInfo { Title = "MyProjectName API", Version = "v1" }); |
|||
options.DocInclusionPredicate((docName, description) => true); |
|||
options.CustomSchemaIds(type => type.FullName); |
|||
} |
|||
); |
|||
} |
|||
|
|||
private void ConfigureDataProtection( |
|||
ServiceConfigurationContext context, |
|||
IConfiguration configuration, |
|||
IWebHostEnvironment hostingEnvironment) |
|||
{ |
|||
var dataProtectionBuilder = context.Services.AddDataProtection().SetApplicationName("MyProjectName"); |
|||
if (!hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); |
|||
dataProtectionBuilder.PersistKeysToStackExchangeRedis(redis, "MyProjectName-Protection-Keys"); |
|||
} |
|||
} |
|||
|
|||
private void ConfigureDistributedLocking( |
|||
ServiceConfigurationContext context, |
|||
IConfiguration configuration) |
|||
{ |
|||
context.Services.AddSingleton<IDistributedLockProvider>(sp => |
|||
{ |
|||
var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!); |
|||
return new RedisDistributedSynchronizationProvider(connection.GetDatabase()); |
|||
}); |
|||
} |
|||
|
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var env = context.GetEnvironment(); |
|||
var app = context.GetApplicationBuilder(); |
|||
|
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
} |
|||
|
|||
app.UseAbpRequestLocalization(); |
|||
|
|||
if (!env.IsDevelopment()) |
|||
{ |
|||
app.UseErrorPage(); |
|||
} |
|||
|
|||
app.UseCorrelationId(); |
|||
app.UseStaticFiles(); |
|||
app.UseRouting(); |
|||
app.UseAuthentication(); |
|||
|
|||
if (MultiTenancyConsts.IsEnabled) |
|||
{ |
|||
app.UseMultiTenancy(); |
|||
} |
|||
app.UseDynamicClaims(); |
|||
app.UseAntiforgery(); |
|||
app.UseAuthorization(); |
|||
app.UseSwagger(); |
|||
app.UseAbpSwaggerUI(options => |
|||
{ |
|||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API"); |
|||
}); |
|||
app.UseAbpSerilogEnrichers(); |
|||
app.UseConfiguredEndpoints(builder => |
|||
{ |
|||
builder.MapRazorComponents<App>() |
|||
.AddInteractiveServerRenderMode() |
|||
.AddInteractiveWebAssemblyRenderMode() |
|||
.AddAdditionalAssemblies(builder.ServiceProvider.GetRequiredService<IOptions<AbpRouterOptions>>().Value.AdditionalAssemblies.ToArray()); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Ui.Branding; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
public class MyProjectNameBrandingProvider : DefaultBrandingProvider |
|||
{ |
|||
public override string AppName => "MyProjectName"; |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using MyCompanyName.MyProjectName.Localization; |
|||
using Volo.Abp.AspNetCore.Components; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered; |
|||
|
|||
public abstract class MyProjectNameComponentBase : AbpComponentBase |
|||
{ |
|||
protected MyProjectNameComponentBase() |
|||
{ |
|||
LocalizationResource = typeof(MyProjectNameResource); |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Serilog; |
|||
using Serilog.Events; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered; |
|||
|
|||
public class Program |
|||
{ |
|||
public async static Task<int> Main(string[] args) |
|||
{ |
|||
Log.Logger = new LoggerConfiguration() |
|||
#if DEBUG
|
|||
.MinimumLevel.Debug() |
|||
#else
|
|||
.MinimumLevel.Information() |
|||
#endif
|
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
|||
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) |
|||
.Enrich.FromLogContext() |
|||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|||
.WriteTo.Async(c => c.Console()) |
|||
.CreateLogger(); |
|||
|
|||
try |
|||
{ |
|||
Log.Information("Starting web host."); |
|||
var builder = WebApplication.CreateBuilder(args); |
|||
builder.Host.AddAppSettingsSecretsJson() |
|||
.UseAutofac() |
|||
.UseSerilog(); |
|||
await builder.AddApplicationAsync<MyProjectNameBlazorModule>(); |
|||
var app = builder.Build(); |
|||
await app.InitializeApplicationAsync(); |
|||
await app.RunAsync(); |
|||
return 0; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
if (ex is HostAbortedException) |
|||
{ |
|||
throw; |
|||
} |
|||
|
|||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "https://localhost:44309/", |
|||
"sslPort": 44309 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered": { |
|||
"commandName": "Project", |
|||
"dotnetRunMessages": "true", |
|||
"launchBrowser": true, |
|||
"applicationUrl": "https://localhost:44309/", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
@using System.Net.Http |
|||
@using Microsoft.AspNetCore.Authorization |
|||
@using Microsoft.AspNetCore.Components.Authorization |
|||
@using Microsoft.AspNetCore.Components.Forms |
|||
@using Microsoft.AspNetCore.Components.Routing |
|||
@using Microsoft.AspNetCore.Components.Web |
|||
@using Microsoft.AspNetCore.Components.Web.Virtualization |
|||
@using static Microsoft.AspNetCore.Components.Web.RenderMode |
|||
@using Microsoft.JSInterop |
|||
@using Blazorise |
|||
@using Blazorise.DataGrid |
|||
@using Volo.Abp.BlazoriseUI |
|||
@using Volo.Abp.BlazoriseUI.Components |
|||
@using MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.Client |
|||
@ -0,0 +1,11 @@ |
|||
module.exports = { |
|||
aliases: { |
|||
|
|||
}, |
|||
clean: [ |
|||
|
|||
], |
|||
mappings: { |
|||
|
|||
} |
|||
}; |
|||
@ -0,0 +1,2 @@ |
|||
{ |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
{ |
|||
"App": { |
|||
"SelfUrl": "https://localhost:44309" |
|||
}, |
|||
"RemoteServices": { |
|||
"Default": { |
|||
"BaseUrl": "https://localhost:44300/" |
|||
} |
|||
}, |
|||
"Redis": { |
|||
"Configuration": "127.0.0.1" |
|||
}, |
|||
"AuthServer": { |
|||
"Authority": "https://localhost:44301", |
|||
"RequireHttpsMetadata": true, |
|||
"ClientId": "MyProjectName_BlazorServerTiered", |
|||
"ClientSecret": "1q2w3e*", |
|||
"IsContainerized": false |
|||
}, |
|||
"StringEncryption": { |
|||
"DefaultPassPhrase": "gsKnGZ041HLL4IM8" |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
{ |
|||
"version": "1.0.0", |
|||
"name": "my-app", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.leptonxlite": "~3.0.1", |
|||
"@abp/aspnetcore.components.server.leptonxlitetheme": "~3.0.1" |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<configuration> |
|||
<location path="." inheritInChildApplications="false"> |
|||
<system.webServer> |
|||
<handlers> |
|||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> |
|||
</handlers> |
|||
<aspNetCore processPath="dotnet" arguments=".\MyCompanyName.MyProjectName.Blazor.Server.WebApp.Tiered.dll" stdoutLogEnabled="false" stdoutLogFile=".\Logs\stdout" hostingModel="inprocess" /> |
|||
</system.webServer> |
|||
</location> |
|||
<system.webServer> |
|||
<httpProtocol> |
|||
<customHeaders> |
|||
<remove name="x-powered-by" /> |
|||
</customHeaders> |
|||
</httpProtocol> |
|||
</system.webServer> |
|||
</configuration> |
|||
@ -0,0 +1,18 @@ |
|||
#blazor-error-ui { |
|||
background: lightyellow; |
|||
bottom: 0; |
|||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); |
|||
display: none; |
|||
left: 0; |
|||
padding: 0.6rem 1.25rem 0.7rem 1.25rem; |
|||
position: fixed; |
|||
width: 100%; |
|||
z-index: 1000; |
|||
} |
|||
|
|||
#blazor-error-ui .dismiss { |
|||
cursor: pointer; |
|||
position: absolute; |
|||
right: 0.75rem; |
|||
top: 0.5rem; |
|||
} |
|||
|
After Width: | Height: | Size: 31 KiB |
@ -0,0 +1,10 @@ |
|||
body { |
|||
|
|||
} |
|||
|
|||
/* <TEMPLATE-REMOVE IF-NOT='LEPTONX'> */ |
|||
:root .lpx-brand-logo { |
|||
--lpx-logo: url('/images/logo/leptonx/logo-light.png'); |
|||
--lpx-logo-icon: url('/images/logo/leptonx/logo-light-thumbnail.png'); |
|||
} |
|||
/* </TEMPLATE-REMOVE> */ |
|||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 38 KiB |