@ -0,0 +1,82 @@ |
|||
using MyCompanyName.MyProjectName.Blazor.Menus; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.Localization; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.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.WebAssembly.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", |
|||
order: 0 |
|||
) |
|||
); |
|||
|
|||
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.Menus; |
|||
|
|||
public class MyProjectNameMenus |
|||
{ |
|||
private const string Prefix = "MyProjectName"; |
|||
public const string Home = Prefix + ".Home"; |
|||
|
|||
//Add your menu items here...
|
|||
|
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Blazorise.Bootstrap5" Version="1.1.4.1" /> |
|||
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.1.4.1" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.0" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.0" /> |
|||
</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="2.0.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" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.HttpApi.Client\Volo.Abp.Account.HttpApi.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.HttpApi.Client\Volo.Abp.Identity.HttpApi.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.HttpApi.Client\Volo.Abp.PermissionManagement.HttpApi.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.HttpApi.Client\Volo.Abp.TenantManagement.HttpApi.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.HttpApi.Client\Volo.Abp.FeatureManagement.HttpApi.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.HttpApi.Client\Volo.Abp.SettingManagement.HttpApi.Client.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\openiddict\src\Volo.Abp.OpenIddict.Domain.Shared\Volo.Abp.OpenIddict.Domain.Shared.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Shared\MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
using AutoMapper; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Client; |
|||
|
|||
public class MyProjectNameBlazorAutoMapperProfile : Profile |
|||
{ |
|||
public MyProjectNameBlazorAutoMapperProfile() |
|||
{ |
|||
//Define your AutoMapper configuration here for the Blazor project.
|
|||
} |
|||
} |
|||
@ -0,0 +1,142 @@ |
|||
using Blazorise.Bootstrap5; |
|||
using Blazorise.Icons.FontAwesome; |
|||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Client.Menus; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared; |
|||
using OpenIddict.Abstractions; |
|||
using Volo.Abp.Account; |
|||
using Volo.Abp.AspNetCore.Components.Web.LeptonXLiteTheme.Themes.LeptonXLite; |
|||
using Volo.Abp.AspNetCore.Components.Web.Theming.Routing; |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme; |
|||
using Volo.Abp.Autofac.WebAssembly; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.FeatureManagement; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Identity.Blazor.WebAssembly; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.OpenIddict; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.SettingManagement; |
|||
using Volo.Abp.SettingManagement.Blazor.WebAssembly; |
|||
using Volo.Abp.TenantManagement; |
|||
using Volo.Abp.TenantManagement.Blazor.WebAssembly; |
|||
using Volo.Abp.UI.Navigation; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Client; |
|||
|
|||
[DependsOn( |
|||
typeof(MyProjectNameSharedModule), |
|||
|
|||
// ABP Framework packages
|
|||
typeof(AbpAutofacWebAssemblyModule), |
|||
typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeModule), |
|||
|
|||
// Account module packages
|
|||
typeof(AbpAccountHttpApiClientModule), |
|||
|
|||
// Identity module packages
|
|||
typeof(AbpIdentityHttpApiClientModule), |
|||
typeof(AbpIdentityBlazorWebAssemblyModule), |
|||
typeof(AbpOpenIddictDomainSharedModule), |
|||
|
|||
// Permission Management module packages
|
|||
typeof(AbpPermissionManagementHttpApiClientModule), |
|||
|
|||
// Tenant Management module packages
|
|||
typeof(AbpTenantManagementHttpApiClientModule), |
|||
typeof(AbpTenantManagementBlazorWebAssemblyModule), |
|||
|
|||
// Feature Management module packages
|
|||
typeof(AbpFeatureManagementHttpApiClientModule), |
|||
|
|||
// Setting Management module packages
|
|||
typeof(AbpSettingManagementHttpApiClientModule), |
|||
typeof(AbpSettingManagementBlazorWebAssemblyModule) |
|||
)] |
|||
public class MyProjectNameBlazorModule : AbpModule |
|||
{ |
|||
public const string RemoteServiceName = "Default"; |
|||
|
|||
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); |
|||
ConfigureUI(builder); |
|||
ConfigureMenu(context); |
|||
ConfigureAutoMapper(context); |
|||
ConfigureHttpClientProxies(context); |
|||
} |
|||
|
|||
private void ConfigureRouter(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpRouterOptions>(options => |
|||
{ |
|||
options.AppAssembly = typeof(MyProjectNameBlazorModule).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 void ConfigureHttpClientProxies(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddHttpClientProxies( |
|||
typeof(MyProjectNameSharedModule).Assembly, |
|||
RemoteServiceName |
|||
); |
|||
} |
|||
|
|||
private static void ConfigureAuthentication(WebAssemblyHostBuilder builder) |
|||
{ |
|||
builder.Services.AddOidcAuthentication(options => |
|||
{ |
|||
builder.Configuration.Bind("AuthServer", options.ProviderOptions); |
|||
options.UserOptions.NameClaim = OpenIddictConstants.Claims.Name; |
|||
options.UserOptions.RoleClaim = OpenIddictConstants.Claims.Role; |
|||
|
|||
options.ProviderOptions.DefaultScopes.Add("MyProjectName"); |
|||
options.ProviderOptions.DefaultScopes.Add("roles"); |
|||
options.ProviderOptions.DefaultScopes.Add("email"); |
|||
options.ProviderOptions.DefaultScopes.Add("phone"); |
|||
}); |
|||
} |
|||
|
|||
private static void ConfigureUI(WebAssemblyHostBuilder builder) |
|||
{ |
|||
builder.RootComponents.Add<App>("#ApplicationContainer"); |
|||
|
|||
} |
|||
|
|||
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<MyProjectNameBlazorModule>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Ui.Branding; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.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.WebAssembly.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.Blazor.WebAssembly.Shared.Localization; |
|||
using Volo.Abp.AspNetCore.Components; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Client; |
|||
|
|||
public abstract class MyProjectNameComponentBase : AbpComponentBase |
|||
{ |
|||
protected MyProjectNameComponentBase() |
|||
{ |
|||
LocalizationResource = typeof(MyProjectNameResource); |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
@page "/" |
|||
@inherits MyProjectNameComponentBase |
|||
<div class="container"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<h5 class="card-title"> |
|||
@L["Welcome_Title"] |
|||
</h5> |
|||
</div> |
|||
<div class="card-body"> |
|||
@L["Welcome_Text"] |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="card mt-5"> |
|||
<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> |
|||
@ -0,0 +1,6 @@ |
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Client.Pages; |
|||
|
|||
public partial class Index |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Client; |
|||
|
|||
public class Program |
|||
{ |
|||
public async static Task Main(string[] args) |
|||
{ |
|||
var builder = WebAssemblyHostBuilder.CreateDefault(args); |
|||
|
|||
var application = await builder.AddApplicationAsync<MyProjectNameBlazorModule>(options => |
|||
{ |
|||
options.UseAutofac(); |
|||
}); |
|||
|
|||
var host = builder.Build(); |
|||
|
|||
await application.InitializeApplicationAsync(host.Services); |
|||
|
|||
await host.RunAsync(); |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "https://localhost:44300", |
|||
"sslPort": 44300 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"https": { |
|||
"commandName": "Project", |
|||
"dotnetRunMessages": true, |
|||
"launchBrowser": true, |
|||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", |
|||
"applicationUrl": "https://localhost:44300", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", |
|||
"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.WebAssembly.Http |
|||
@using Microsoft.JSInterop |
|||
@using Volo.Abp.AspNetCore.Components.Web |
|||
@using MyCompanyName.MyProjectName.Blazor.WebAssembly.Client |
|||
@using Blazorise |
|||
@using Blazorise.DataGrid |
|||
@using Volo.Abp.BlazoriseUI |
|||
@using Volo.Abp.BlazoriseUI.Components |
|||
@ -0,0 +1,24 @@ |
|||
{ |
|||
"App": { |
|||
"SelfUrl": "https://localhost:44300" |
|||
}, |
|||
"AuthServer": { |
|||
"Authority": "https://localhost:44300", |
|||
"ClientId": "MyProjectName_Blazor", |
|||
"ResponseType": "code" |
|||
}, |
|||
"RemoteServices": { |
|||
"Default": { |
|||
"BaseUrl": "https://localhost:44300" |
|||
} |
|||
}, |
|||
"AbpCli": { |
|||
"Bundle": { |
|||
"Mode": "BundleAndMinify", /* Options: None, Bundle, BundleAndMinify */ |
|||
"Name": "global", |
|||
"Parameters": { |
|||
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1,35 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
|
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> |
|||
<title>MyCompanyName.MyProjectName.Blazor</title> |
|||
<base href="/" /> |
|||
|
|||
<!--ABP:Styles--> |
|||
<link href="global.css?_v=638058527301625844" rel="stylesheet"/> |
|||
<link href="main.css" rel="stylesheet"/> |
|||
<!--/ABP:Styles--> |
|||
<link href="MyCompanyName.MyProjectName.Blazor.styles.css" rel="stylesheet"/> |
|||
|
|||
<!-- <TEMPLATE-REMOVE IF-NOT='PWA'> --> |
|||
<link href="manifest.json" rel="manifest" /> |
|||
<link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" /> |
|||
<link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" /> |
|||
<!-- </TEMPLATE-REMOVE> --> |
|||
</head> |
|||
|
|||
<body class="abp-application-layout bg-light"> |
|||
<div id="ApplicationContainer"> |
|||
<div class="spinner"> |
|||
<div class="double-bounce1"></div> |
|||
<div class="double-bounce2"></div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!--ABP:Scripts--> |
|||
<script src="global.js?_v=638058527305084060"></script> |
|||
<!--/ABP:Scripts--> |
|||
</body> |
|||
</html> |
|||
@ -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,36 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.AuditLogging.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.FeatureManagement.EntityFrameworkCore; |
|||
using Volo.Abp.Identity.EntityFrameworkCore; |
|||
using Volo.Abp.OpenIddict.EntityFrameworkCore; |
|||
using Volo.Abp.PermissionManagement.EntityFrameworkCore; |
|||
using Volo.Abp.SettingManagement.EntityFrameworkCore; |
|||
using Volo.Abp.TenantManagement.EntityFrameworkCore; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.Data; |
|||
|
|||
public class MyProjectNameDbContext : AbpDbContext<MyProjectNameDbContext> |
|||
{ |
|||
public MyProjectNameDbContext(DbContextOptions<MyProjectNameDbContext> options) |
|||
: base(options) |
|||
{ |
|||
} |
|||
|
|||
protected override void OnModelCreating(ModelBuilder builder) |
|||
{ |
|||
base.OnModelCreating(builder); |
|||
|
|||
/* Include modules to your migration db context */ |
|||
|
|||
builder.ConfigurePermissionManagement(); |
|||
builder.ConfigureSettingManagement(); |
|||
builder.ConfigureAuditLogging(); |
|||
builder.ConfigureIdentity(); |
|||
builder.ConfigureOpenIddict(); |
|||
builder.ConfigureFeatureManagement(); |
|||
builder.ConfigureTenantManagement(); |
|||
|
|||
/* Configure your own entities here */ |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.EntityFrameworkCore.Design; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.Data; |
|||
|
|||
public class MyProjectNameDbContextFactory : IDesignTimeDbContextFactory<MyProjectNameDbContext> |
|||
{ |
|||
public MyProjectNameDbContext CreateDbContext(string[] args) |
|||
{ |
|||
//<TEMPLATE-REMOVE IF-NOT='dbms:PostgreSQL'>
|
|||
// https://www.npgsql.org/efcore/release-notes/6.0.html#opting-out-of-the-new-timestamp-mapping-logic
|
|||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); |
|||
//</TEMPLATE-REMOVE>
|
|||
|
|||
var configuration = BuildConfiguration(); |
|||
|
|||
var builder = new DbContextOptionsBuilder<MyProjectNameDbContext>() |
|||
.UseSqlServer(configuration.GetConnectionString("Default")); |
|||
|
|||
return new MyProjectNameDbContext(builder.Options); |
|||
} |
|||
|
|||
private static IConfigurationRoot BuildConfiguration() |
|||
{ |
|||
var builder = new ConfigurationBuilder() |
|||
.SetBasePath(Directory.GetCurrentDirectory()) |
|||
.AddJsonFile("appsettings.json", optional: false); |
|||
|
|||
return builder.Build(); |
|||
} |
|||
} |
|||
@ -0,0 +1,203 @@ |
|||
using System.Diagnostics; |
|||
using System.Runtime.InteropServices; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.TenantManagement; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.Data; |
|||
|
|||
public class MyProjectNameDbMigrationService : ITransientDependency |
|||
{ |
|||
public ILogger<MyProjectNameDbMigrationService> Logger { get; set; } |
|||
|
|||
private readonly IDataSeeder _dataSeeder; |
|||
private readonly MyProjectNameEFCoreDbSchemaMigrator _dbSchemaMigrator; |
|||
private readonly ITenantRepository _tenantRepository; |
|||
private readonly ICurrentTenant _currentTenant; |
|||
|
|||
public MyProjectNameDbMigrationService( |
|||
IDataSeeder dataSeeder, |
|||
MyProjectNameEFCoreDbSchemaMigrator dbSchemaMigrator, |
|||
ITenantRepository tenantRepository, |
|||
ICurrentTenant currentTenant) |
|||
{ |
|||
_dataSeeder = dataSeeder; |
|||
_dbSchemaMigrator = dbSchemaMigrator; |
|||
_tenantRepository = tenantRepository; |
|||
_currentTenant = currentTenant; |
|||
|
|||
Logger = NullLogger<MyProjectNameDbMigrationService>.Instance; |
|||
} |
|||
|
|||
public async Task MigrateAsync() |
|||
{ |
|||
var initialMigrationAdded = AddInitialMigrationIfNotExist(); |
|||
|
|||
if (initialMigrationAdded) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
Logger.LogInformation("Started database migrations..."); |
|||
|
|||
await MigrateDatabaseSchemaAsync(); |
|||
await SeedDataAsync(); |
|||
|
|||
Logger.LogInformation($"Successfully completed host database migrations."); |
|||
|
|||
var tenants = await _tenantRepository.GetListAsync(includeDetails: true); |
|||
|
|||
var migratedDatabaseSchemas = new HashSet<string>(); |
|||
foreach (var tenant in tenants) |
|||
{ |
|||
using (_currentTenant.Change(tenant.Id)) |
|||
{ |
|||
if (tenant.ConnectionStrings.Any()) |
|||
{ |
|||
var tenantConnectionStrings = tenant.ConnectionStrings |
|||
.Select(x => x.Value) |
|||
.ToList(); |
|||
|
|||
if (!migratedDatabaseSchemas.IsSupersetOf(tenantConnectionStrings)) |
|||
{ |
|||
await MigrateDatabaseSchemaAsync(tenant); |
|||
|
|||
migratedDatabaseSchemas.AddIfNotContains(tenantConnectionStrings); |
|||
} |
|||
} |
|||
|
|||
await SeedDataAsync(tenant); |
|||
} |
|||
|
|||
Logger.LogInformation($"Successfully completed {tenant.Name} tenant database migrations."); |
|||
} |
|||
|
|||
Logger.LogInformation("Successfully completed all database migrations."); |
|||
Logger.LogInformation("You can safely end this process..."); |
|||
} |
|||
|
|||
private async Task MigrateDatabaseSchemaAsync(Tenant? tenant = null) |
|||
{ |
|||
Logger.LogInformation($"Migrating schema for {(tenant == null ? "host" : tenant.Name + " tenant")} database..."); |
|||
await _dbSchemaMigrator.MigrateAsync(); |
|||
} |
|||
|
|||
private async Task SeedDataAsync(Tenant? tenant = null) |
|||
{ |
|||
Logger.LogInformation($"Executing {(tenant == null ? "host" : tenant.Name + " tenant")} database seed..."); |
|||
|
|||
await _dataSeeder.SeedAsync(new DataSeedContext(tenant?.Id) |
|||
.WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, IdentityDataSeedContributor.AdminEmailDefaultValue) |
|||
.WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, IdentityDataSeedContributor.AdminPasswordDefaultValue) |
|||
); |
|||
} |
|||
|
|||
private bool AddInitialMigrationIfNotExist() |
|||
{ |
|||
try |
|||
{ |
|||
if (!DbMigrationsProjectExists()) |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
try |
|||
{ |
|||
if (!MigrationsFolderExists()) |
|||
{ |
|||
AddInitialMigration(); |
|||
return true; |
|||
} |
|||
else |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
Logger.LogWarning("Couldn't determinate if any migrations exist : " + e.Message); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
private bool DbMigrationsProjectExists() |
|||
{ |
|||
return Directory.Exists(GetEntityFrameworkCoreProjectFolderPath()); |
|||
} |
|||
|
|||
private bool MigrationsFolderExists() |
|||
{ |
|||
var dbMigrationsProjectFolder = GetEntityFrameworkCoreProjectFolderPath(); |
|||
|
|||
return Directory.Exists(Path.Combine(dbMigrationsProjectFolder, "Migrations")); |
|||
} |
|||
|
|||
private void AddInitialMigration() |
|||
{ |
|||
Logger.LogInformation("Creating initial migration..."); |
|||
|
|||
string argumentPrefix; |
|||
string fileName; |
|||
|
|||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) |
|||
{ |
|||
argumentPrefix = "-c"; |
|||
fileName = "/bin/bash"; |
|||
} |
|||
else |
|||
{ |
|||
argumentPrefix = "/C"; |
|||
fileName = "cmd.exe"; |
|||
} |
|||
|
|||
var procStartInfo = new ProcessStartInfo(fileName, |
|||
$"{argumentPrefix} \"abp create-migration-and-run-migrator \"{GetEntityFrameworkCoreProjectFolderPath()}\" --nolayers\"" |
|||
); |
|||
|
|||
try |
|||
{ |
|||
Process.Start(procStartInfo); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
throw new Exception("Couldn't run ABP CLI..."); |
|||
} |
|||
} |
|||
|
|||
private string GetEntityFrameworkCoreProjectFolderPath() |
|||
{ |
|||
var slnDirectoryPath = GetSolutionDirectoryPath(); |
|||
|
|||
if (slnDirectoryPath == null) |
|||
{ |
|||
throw new Exception("Solution folder not found!"); |
|||
} |
|||
|
|||
return Path.Combine(slnDirectoryPath, "MyCompanyName.MyProjectName.Host"); |
|||
} |
|||
|
|||
private string? GetSolutionDirectoryPath() |
|||
{ |
|||
var currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory()); |
|||
|
|||
while (currentDirectory != null && Directory.GetParent(currentDirectory.FullName) != null) |
|||
{ |
|||
currentDirectory = Directory.GetParent(currentDirectory.FullName); |
|||
|
|||
if (currentDirectory != null && Directory.GetFiles(currentDirectory.FullName).FirstOrDefault(f => f.EndsWith(".sln")) != null) |
|||
{ |
|||
return currentDirectory.FullName; |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.Data; |
|||
|
|||
public class MyProjectNameEFCoreDbSchemaMigrator : ITransientDependency |
|||
{ |
|||
private readonly IServiceProvider _serviceProvider; |
|||
|
|||
public MyProjectNameEFCoreDbSchemaMigrator( |
|||
IServiceProvider serviceProvider) |
|||
{ |
|||
_serviceProvider = serviceProvider; |
|||
} |
|||
|
|||
public async Task MigrateAsync() |
|||
{ |
|||
/* We intentionally resolving the MyProjectNameDbContext |
|||
* from IServiceProvider (instead of directly injecting it) |
|||
* to properly get the connection string of the current tenant in the |
|||
* current scope. |
|||
*/ |
|||
|
|||
await _serviceProvider |
|||
.GetRequiredService<MyProjectNameDbContext>() |
|||
.Database |
|||
.MigrateAsync(); |
|||
} |
|||
} |
|||
@ -0,0 +1,308 @@ |
|||
using JetBrains.Annotations; |
|||
using Microsoft.Extensions.Localization; |
|||
using OpenIddict.Abstractions; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.OpenIddict.Applications; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.Data; |
|||
|
|||
/* Creates initial data that is needed to property run the application |
|||
* and make client-to-server communication possible. |
|||
*/ |
|||
public class OpenIddictDataSeedContributor : IDataSeedContributor, ITransientDependency |
|||
{ |
|||
private readonly IConfiguration _configuration; |
|||
private readonly IOpenIddictApplicationManager _applicationManager; |
|||
private readonly IOpenIddictScopeManager _scopeManager; |
|||
private readonly IPermissionDataSeeder _permissionDataSeeder; |
|||
private readonly IStringLocalizer<OpenIddictResponse> L; |
|||
|
|||
public OpenIddictDataSeedContributor( |
|||
IConfiguration configuration, |
|||
IOpenIddictApplicationManager applicationManager, |
|||
IOpenIddictScopeManager scopeManager, |
|||
IPermissionDataSeeder permissionDataSeeder, |
|||
IStringLocalizer<OpenIddictResponse> l) |
|||
{ |
|||
_configuration = configuration; |
|||
_applicationManager = applicationManager; |
|||
_scopeManager = scopeManager; |
|||
_permissionDataSeeder = permissionDataSeeder; |
|||
L = l; |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public virtual async Task SeedAsync(DataSeedContext context) |
|||
{ |
|||
await CreateScopesAsync(); |
|||
await CreateApplicationsAsync(); |
|||
} |
|||
|
|||
private async Task CreateScopesAsync() |
|||
{ |
|||
if (await _scopeManager.FindByNameAsync("MyProjectName") == null) |
|||
{ |
|||
await _scopeManager.CreateAsync(new OpenIddictScopeDescriptor |
|||
{ |
|||
Name = "MyProjectName", |
|||
DisplayName = "MyProjectName API", |
|||
Resources = |
|||
{ |
|||
"MyProjectName" |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
private async Task CreateApplicationsAsync() |
|||
{ |
|||
var commonScopes = new List<string> |
|||
{ |
|||
OpenIddictConstants.Permissions.Scopes.Address, |
|||
OpenIddictConstants.Permissions.Scopes.Email, |
|||
OpenIddictConstants.Permissions.Scopes.Phone, |
|||
OpenIddictConstants.Permissions.Scopes.Profile, |
|||
OpenIddictConstants.Permissions.Scopes.Roles, |
|||
"MyProjectName" |
|||
}; |
|||
|
|||
var configurationSection = _configuration.GetSection("OpenIddict:Applications"); |
|||
|
|||
//Blazor Client
|
|||
var blazorClientId = configurationSection["MyProjectName_Blazor:ClientId"]; |
|||
if (!blazorClientId.IsNullOrWhiteSpace()) |
|||
{ |
|||
var blazorRootUrl = configurationSection["MyProjectName_Blazor:RootUrl"]?.TrimEnd('/'); |
|||
await CreateApplicationAsync( |
|||
name: blazorClientId!, |
|||
type: OpenIddictConstants.ClientTypes.Public, |
|||
consentType: OpenIddictConstants.ConsentTypes.Implicit, |
|||
displayName: "Blazor Application", |
|||
secret: null, |
|||
grantTypes: new List<string> |
|||
{ |
|||
OpenIddictConstants.GrantTypes.AuthorizationCode |
|||
}, |
|||
scopes: commonScopes, |
|||
redirectUri: $"{blazorRootUrl}/authentication/login-callback", |
|||
clientUri: blazorRootUrl, |
|||
postLogoutRedirectUri: $"{blazorRootUrl}/authentication/logout-callback" |
|||
); |
|||
} |
|||
|
|||
// Swagger Client
|
|||
var swaggerClientId = configurationSection["MyProjectName_Swagger:ClientId"]; |
|||
if (!swaggerClientId.IsNullOrWhiteSpace()) |
|||
{ |
|||
var swaggerRootUrl = configurationSection["MyProjectName_Swagger:RootUrl"]?.TrimEnd('/'); |
|||
|
|||
await CreateApplicationAsync( |
|||
name: swaggerClientId!, |
|||
type: OpenIddictConstants.ClientTypes.Public, |
|||
consentType: OpenIddictConstants.ConsentTypes.Implicit, |
|||
displayName: "Swagger Application", |
|||
secret: null, |
|||
grantTypes: new List<string> |
|||
{ |
|||
OpenIddictConstants.GrantTypes.AuthorizationCode, |
|||
}, |
|||
scopes: commonScopes, |
|||
redirectUri: $"{swaggerRootUrl}/swagger/oauth2-redirect.html" |
|||
); |
|||
} |
|||
} |
|||
|
|||
private async Task CreateApplicationAsync( |
|||
[NotNull] string name, |
|||
[NotNull] string type, |
|||
[NotNull] string consentType, |
|||
string displayName, |
|||
string? secret, |
|||
List<string> grantTypes, |
|||
List<string> scopes, |
|||
string? clientUri = null, |
|||
string? redirectUri = null, |
|||
string? postLogoutRedirectUri = null, |
|||
List<string>? permissions = null) |
|||
{ |
|||
if (!string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) |
|||
{ |
|||
throw new BusinessException(L["NoClientSecretCanBeSetForPublicApplications"]); |
|||
} |
|||
|
|||
if (string.IsNullOrEmpty(secret) && string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase)) |
|||
{ |
|||
throw new BusinessException(L["TheClientSecretIsRequiredForConfidentialApplications"]); |
|||
} |
|||
|
|||
if (!string.IsNullOrEmpty(name) && await _applicationManager.FindByClientIdAsync(name) != null) |
|||
{ |
|||
return; |
|||
//throw new BusinessException(L["TheClientIdentifierIsAlreadyTakenByAnotherApplication"]);
|
|||
} |
|||
|
|||
var client = await _applicationManager.FindByClientIdAsync(name); |
|||
if (client == null) |
|||
{ |
|||
var application = new AbpApplicationDescriptor |
|||
{ |
|||
ClientId = name, |
|||
Type = type, |
|||
ClientSecret = secret, |
|||
ConsentType = consentType, |
|||
DisplayName = displayName, |
|||
ClientUri = clientUri |
|||
}; |
|||
|
|||
Check.NotNullOrEmpty(grantTypes, nameof(grantTypes)); |
|||
Check.NotNullOrEmpty(scopes, nameof(scopes)); |
|||
|
|||
if (new [] { OpenIddictConstants.GrantTypes.AuthorizationCode, OpenIddictConstants.GrantTypes.Implicit }.All(grantTypes.Contains)) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdToken); |
|||
|
|||
if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeIdTokenToken); |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.CodeToken); |
|||
} |
|||
} |
|||
|
|||
if (!redirectUri.IsNullOrWhiteSpace() || !postLogoutRedirectUri.IsNullOrWhiteSpace()) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Logout); |
|||
} |
|||
|
|||
foreach (var grantType in grantTypes) |
|||
{ |
|||
if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode); |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Code); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || grantType == OpenIddictConstants.GrantTypes.Implicit) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Authorization); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.AuthorizationCode || |
|||
grantType == OpenIddictConstants.GrantTypes.ClientCredentials || |
|||
grantType == OpenIddictConstants.GrantTypes.Password || |
|||
grantType == OpenIddictConstants.GrantTypes.RefreshToken || |
|||
grantType == OpenIddictConstants.GrantTypes.DeviceCode) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Token); |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Revocation); |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Introspection); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.ClientCredentials) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.ClientCredentials); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.Implicit) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Implicit); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.Password) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.Password); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.RefreshToken) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.RefreshToken); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.DeviceCode) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.GrantTypes.DeviceCode); |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.Endpoints.Device); |
|||
} |
|||
|
|||
if (grantType == OpenIddictConstants.GrantTypes.Implicit) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdToken); |
|||
if (string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.IdTokenToken); |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.ResponseTypes.Token); |
|||
} |
|||
} |
|||
} |
|||
|
|||
var buildInScopes = new [] |
|||
{ |
|||
OpenIddictConstants.Permissions.Scopes.Address, |
|||
OpenIddictConstants.Permissions.Scopes.Email, |
|||
OpenIddictConstants.Permissions.Scopes.Phone, |
|||
OpenIddictConstants.Permissions.Scopes.Profile, |
|||
OpenIddictConstants.Permissions.Scopes.Roles |
|||
}; |
|||
|
|||
foreach (var scope in scopes) |
|||
{ |
|||
if (buildInScopes.Contains(scope)) |
|||
{ |
|||
application.Permissions.Add(scope); |
|||
} |
|||
else |
|||
{ |
|||
application.Permissions.Add(OpenIddictConstants.Permissions.Prefixes.Scope + scope); |
|||
} |
|||
} |
|||
|
|||
if (redirectUri != null) |
|||
{ |
|||
if (!redirectUri.IsNullOrEmpty()) |
|||
{ |
|||
if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString()) |
|||
{ |
|||
throw new BusinessException(L["InvalidRedirectUri", redirectUri]); |
|||
} |
|||
|
|||
if (application.RedirectUris.All(x => x != uri)) |
|||
{ |
|||
application.RedirectUris.Add(uri); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (postLogoutRedirectUri != null) |
|||
{ |
|||
if (!postLogoutRedirectUri.IsNullOrEmpty()) |
|||
{ |
|||
if (!Uri.TryCreate(postLogoutRedirectUri, UriKind.Absolute, out var uri) || !uri.IsWellFormedOriginalString()) |
|||
{ |
|||
throw new BusinessException(L["InvalidPostLogoutRedirectUri", postLogoutRedirectUri]); |
|||
} |
|||
|
|||
if (application.PostLogoutRedirectUris.All(x => x != uri)) |
|||
{ |
|||
application.PostLogoutRedirectUris.Add(uri); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (permissions != null) |
|||
{ |
|||
await _permissionDataSeeder.SeedAsync( |
|||
ClientPermissionValueProvider.ProviderName, |
|||
name, |
|||
permissions, |
|||
null |
|||
); |
|||
} |
|||
|
|||
await _applicationManager.CreateAsync(application); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,118 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Serilog.AspNetCore" Version="5.0.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Mvc\Volo.Abp.AspNetCore.Mvc.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Swashbuckle\Volo.Abp.Swashbuckle.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Authentication.JwtBearer\Volo.Abp.AspNetCore.Authentication.JwtBearer.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.Serilog\Volo.Abp.AspNetCore.Serilog.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.EntityFrameworkCore.SqlServer\Volo.Abp.EntityFrameworkCore.SqlServer.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.Application\Volo.Abp.Account.Application.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.HttpApi\Volo.Abp.Account.HttpApi.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\account\src\Volo.Abp.Account.Web.OpenIddict\Volo.Abp.Account.Web.OpenIddict.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.PermissionManagement.Domain.Identity\Volo.Abp.PermissionManagement.Domain.Identity.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.Application\Volo.Abp.Identity.Application.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.HttpApi\Volo.Abp.Identity.HttpApi.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\identity\src\Volo.Abp.Identity.EntityFrameworkCore\Volo.Abp.Identity.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\openiddict\src\Volo.Abp.OpenIddict.EntityFrameworkCore\Volo.Abp.OpenIddict.EntityFrameworkCore.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\openiddict\src\Volo.Abp.PermissionManagement.Domain.OpenIddict\Volo.Abp.PermissionManagement.Domain.OpenIddict.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.Application\Volo.Abp.PermissionManagement.Application.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.EntityFrameworkCore\Volo.Abp.PermissionManagement.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.HttpApi\Volo.Abp.PermissionManagement.HttpApi.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.Application\Volo.Abp.TenantManagement.Application.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.EntityFrameworkCore\Volo.Abp.TenantManagement.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\tenant-management\src\Volo.Abp.TenantManagement.HttpApi\Volo.Abp.TenantManagement.HttpApi.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.Application\Volo.Abp.FeatureManagement.Application.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.EntityFrameworkCore\Volo.Abp.FeatureManagement.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\feature-management\src\Volo.Abp.FeatureManagement.HttpApi\Volo.Abp.FeatureManagement.HttpApi.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.Application\Volo.Abp.SettingManagement.Application.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.EntityFrameworkCore\Volo.Abp.SettingManagement.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\..\..\..\..\modules\setting-management\src\Volo.Abp.SettingManagement.HttpApi\Volo.Abp.SettingManagement.HttpApi.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\modules\audit-logging\src\Volo.Abp.AuditLogging.EntityFrameworkCore\Volo.Abp.AuditLogging.EntityFrameworkCore.csproj" /> |
|||
</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" /> |
|||
<!-- </TEMPLATE-REMOVE> --> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="2.0.0-*" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="7.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0"> |
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> |
|||
<PrivateAssets>compile; contentFiles; build; buildMultitargeting; buildTransitive; analyzers; native</PrivateAssets> |
|||
</PackageReference> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Client\MyCompanyName.MyProjectName.Blazor.WebAssembly.Client.csproj" /> |
|||
<ProjectReference Include="..\Shared\MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Compile Remove="Logs\**" /> |
|||
<Content Remove="Logs\**" /> |
|||
<EmbeddedResource Remove="Logs\**" /> |
|||
<None Remove="Logs\**" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Reference Include="Volo.Abp.AspNetCore.MultiTenancy"> |
|||
<HintPath>..\..\..\..\..\..\framework\src\Volo.Abp.AspNetCore.MultiTenancy\bin\Debug\net7.0\Volo.Abp.AspNetCore.MultiTenancy.dll</HintPath> |
|||
</Reference> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<_ContentIncludedByDefault Remove="Pages\Error.cshtml" /> |
|||
</ItemGroup> |
|||
|
|||
|
|||
</Project> |
|||
@ -0,0 +1,335 @@ |
|||
using Microsoft.AspNetCore.Cors; |
|||
using Microsoft.AspNetCore.DataProtection; |
|||
using Microsoft.AspNetCore.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Microsoft.OpenApi.Models; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.Data; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.Localization; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.MultiTenancy; |
|||
using OpenIddict.Validation.AspNetCore; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Account; |
|||
using Volo.Abp.Account.Web; |
|||
using Volo.Abp.AspNetCore.MultiTenancy; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.Localization; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
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.Serilog; |
|||
using Volo.Abp.AuditLogging.EntityFrameworkCore; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Emailing; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore.SqlServer; |
|||
using Volo.Abp.FeatureManagement; |
|||
using Volo.Abp.FeatureManagement.EntityFrameworkCore; |
|||
using Volo.Abp.Identity; |
|||
using Volo.Abp.Identity.EntityFrameworkCore; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.OpenIddict.EntityFrameworkCore; |
|||
using Volo.Abp.PermissionManagement; |
|||
using Volo.Abp.PermissionManagement.EntityFrameworkCore; |
|||
using Volo.Abp.PermissionManagement.HttpApi; |
|||
using Volo.Abp.PermissionManagement.Identity; |
|||
using Volo.Abp.PermissionManagement.OpenIddict; |
|||
using Volo.Abp.SettingManagement; |
|||
using Volo.Abp.SettingManagement.EntityFrameworkCore; |
|||
using Volo.Abp.Swashbuckle; |
|||
using Volo.Abp.TenantManagement; |
|||
using Volo.Abp.TenantManagement.EntityFrameworkCore; |
|||
using Volo.Abp.UI.Navigation.Urls; |
|||
using Volo.Abp.Uow; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Server; |
|||
|
|||
[DependsOn( |
|||
|
|||
typeof(MyProjectNameSharedModule), |
|||
|
|||
// ABP Framework packages
|
|||
typeof(AbpAspNetCoreMvcModule), |
|||
typeof(AbpAspNetCoreMultiTenancyModule), |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpAutoMapperModule), |
|||
typeof(AbpEntityFrameworkCoreSqlServerModule), |
|||
typeof(AbpAspNetCoreMvcUiLeptonXLiteThemeModule), |
|||
typeof(AbpSwashbuckleModule), |
|||
typeof(AbpAspNetCoreSerilogModule), |
|||
|
|||
// Account module packages
|
|||
typeof(AbpAccountApplicationModule), |
|||
typeof(AbpAccountHttpApiModule), |
|||
typeof(AbpAccountWebOpenIddictModule), |
|||
|
|||
// Identity module packages
|
|||
typeof(AbpPermissionManagementDomainIdentityModule), |
|||
typeof(AbpPermissionManagementDomainOpenIddictModule), |
|||
typeof(AbpIdentityApplicationModule), |
|||
typeof(AbpIdentityHttpApiModule), |
|||
typeof(AbpIdentityEntityFrameworkCoreModule), |
|||
typeof(AbpOpenIddictEntityFrameworkCoreModule), |
|||
|
|||
// Audit logging module packages
|
|||
typeof(AbpAuditLoggingEntityFrameworkCoreModule), |
|||
|
|||
// Permission Management module packages
|
|||
typeof(AbpPermissionManagementApplicationModule), |
|||
typeof(AbpPermissionManagementHttpApiModule), |
|||
typeof(AbpPermissionManagementEntityFrameworkCoreModule), |
|||
|
|||
// Tenant Management module packages
|
|||
typeof(AbpTenantManagementApplicationModule), |
|||
typeof(AbpTenantManagementHttpApiModule), |
|||
typeof(AbpTenantManagementEntityFrameworkCoreModule), |
|||
|
|||
// Feature Management module packages
|
|||
typeof(AbpFeatureManagementApplicationModule), |
|||
typeof(AbpFeatureManagementEntityFrameworkCoreModule), |
|||
typeof(AbpFeatureManagementHttpApiModule), |
|||
|
|||
// Setting Management module packages
|
|||
typeof(AbpSettingManagementApplicationModule), |
|||
typeof(AbpSettingManagementEntityFrameworkCoreModule), |
|||
typeof(AbpSettingManagementHttpApiModule) |
|||
)] |
|||
public class MyProjectNameServerModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options => |
|||
{ |
|||
options.AddAssemblyResource( |
|||
typeof(MyProjectNameResource) |
|||
); |
|||
}); |
|||
|
|||
PreConfigure<OpenIddictBuilder>(builder => |
|||
{ |
|||
builder.AddValidation(options => |
|||
{ |
|||
options.AddAudiences("MyProjectName"); |
|||
options.UseLocalServer(); |
|||
options.UseAspNetCore(); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var hostingEnvironment = context.Services.GetHostingEnvironment(); |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
if (hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>()); |
|||
} |
|||
|
|||
ConfigureAuthentication(context); |
|||
ConfigureBundles(); |
|||
ConfigureMultiTenancy(); |
|||
ConfigureUrls(configuration); |
|||
ConfigureAutoMapper(context); |
|||
ConfigureSwagger(context.Services, configuration); |
|||
ConfigureAutoApiControllers(); |
|||
ConfigureVirtualFiles(hostingEnvironment); |
|||
ConfigureCors(context, configuration); |
|||
ConfigureDataProtection(context); |
|||
ConfigureEfCore(context); |
|||
} |
|||
|
|||
private void ConfigureAuthentication(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.ForwardIdentityAuthenticationForBearer(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); |
|||
} |
|||
|
|||
private void ConfigureBundles() |
|||
{ |
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
options.StyleBundles.Configure( |
|||
LeptonXLiteThemeBundles.Styles.Global, |
|||
bundle => { bundle.AddFiles("/global-styles.css"); } |
|||
); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureMultiTenancy() |
|||
{ |
|||
Configure<AbpMultiTenancyOptions>(options => |
|||
{ |
|||
options.IsEnabled = MultiTenancyConsts.IsEnabled; |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureUrls(IConfiguration configuration) |
|||
{ |
|||
Configure<AppUrlOptions>(options => |
|||
{ |
|||
options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; |
|||
options.RedirectAllowedUrls.AddRange(configuration["App:RedirectAllowedUrls"]?.Split(',') ?? Array.Empty<string>()); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureVirtualFiles(IWebHostEnvironment hostingEnvironment) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<MyProjectNameServerModule>(); |
|||
if (hostingEnvironment.IsDevelopment()) |
|||
{ |
|||
/* Using physical files in development, so we don't need to recompile on changes */ |
|||
options.FileSets.ReplaceEmbeddedByPhysical<MyProjectNameServerModule>(hostingEnvironment.ContentRootPath); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureAutoApiControllers() |
|||
{ |
|||
Configure<AbpAspNetCoreMvcOptions>(options => |
|||
{ |
|||
options.ConventionalControllers.Create(typeof(MyProjectNameServerModule).Assembly); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureSwagger(IServiceCollection services, IConfiguration configuration) |
|||
{ |
|||
services.AddAbpSwaggerGenWithOAuth( |
|||
configuration["AuthServer:Authority"], |
|||
new Dictionary<string, string> |
|||
{ |
|||
{"MyProjectName", "MyProjectName API"} |
|||
}, |
|||
options => |
|||
{ |
|||
options.SwaggerDoc("v1", new OpenApiInfo { Title = "MyProjectName API", Version = "v1" }); |
|||
options.DocInclusionPredicate((docName, description) => true); |
|||
options.CustomSchemaIds(type => type.FullName); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureAutoMapper(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAutoMapperObjectMapper<MyProjectNameServerModule>(); |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
/* Uncomment `validate: true` if you want to enable the Configuration Validation feature. |
|||
* See AutoMapper's documentation to learn what it is: |
|||
* https://docs.automapper.org/en/stable/Configuration-validation.html
|
|||
*/ |
|||
options.AddMaps<MyProjectNameServerModule>(/* validate: true */); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) |
|||
{ |
|||
context.Services.AddCors(options => |
|||
{ |
|||
options.AddDefaultPolicy(builder => |
|||
{ |
|||
builder |
|||
.WithOrigins( |
|||
configuration["App:CorsOrigins"]? |
|||
.Split(",", StringSplitOptions.RemoveEmptyEntries) |
|||
.Select(o => o.RemovePostFix("/")) |
|||
.ToArray() ?? Array.Empty<string>() |
|||
) |
|||
.WithAbpExposedHeaders() |
|||
.SetIsOriginAllowedToAllowWildcardSubdomains() |
|||
.AllowAnyHeader() |
|||
.AllowAnyMethod() |
|||
.AllowCredentials(); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
private void ConfigureDataProtection(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddDataProtection().SetApplicationName("MyProjectName"); |
|||
} |
|||
|
|||
private void ConfigureEfCore(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAbpDbContext<MyProjectNameDbContext>(options => |
|||
{ |
|||
/* You can remove "includeAllEntities: true" to create |
|||
* default repositories only for aggregate roots |
|||
* Documentation: https://docs.abp.io/en/abp/latest/Entity-Framework-Core#add-default-repositories
|
|||
*/ |
|||
options.AddDefaultRepositories(includeAllEntities: true); |
|||
}); |
|||
|
|||
Configure<AbpDbContextOptions>(options => |
|||
{ |
|||
options.Configure(configurationContext => |
|||
{ |
|||
configurationContext.UseSqlServer(); |
|||
}); |
|||
}); |
|||
|
|||
//<TEMPLATE-REMOVE IF-NOT='dbms:SQLite'>
|
|||
Configure<AbpUnitOfWorkDefaultOptions>(options => |
|||
{ |
|||
options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; |
|||
}); |
|||
//</TEMPLATE-REMOVE>
|
|||
} |
|||
|
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var app = context.GetApplicationBuilder(); |
|||
var env = context.GetEnvironment(); |
|||
|
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
} |
|||
|
|||
app.UseAbpRequestLocalization(); |
|||
|
|||
if (!env.IsDevelopment()) |
|||
{ |
|||
app.UseErrorPage(); |
|||
} |
|||
|
|||
app.UseCorrelationId(); |
|||
app.UseBlazorFrameworkFiles(); |
|||
app.UseStaticFiles(); |
|||
app.UseRouting(); |
|||
app.UseCors(); |
|||
app.UseAuthentication(); |
|||
app.UseAbpOpenIddictValidation(); |
|||
|
|||
if (MultiTenancyConsts.IsEnabled) |
|||
{ |
|||
app.UseMultiTenancy(); |
|||
} |
|||
|
|||
app.UseUnitOfWork(); |
|||
app.UseAuthorization(); |
|||
|
|||
app.UseSwagger(); |
|||
app.UseAbpSwaggerUI(options => |
|||
{ |
|||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "MyProjectName API"); |
|||
|
|||
var configuration = context.GetConfiguration(); |
|||
options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); |
|||
options.OAuthScopes("MyProjectName"); |
|||
}); |
|||
|
|||
app.UseAuditing(); |
|||
app.UseAbpSerilogEnrichers(); |
|||
app.UseConfiguredEndpoints(); |
|||
|
|||
if (app is WebApplication webApp) |
|||
{ |
|||
webApp.MapFallbackToFile("index.html"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using AutoMapper; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.ObjectMapping; |
|||
|
|||
public class MyProjectNameAutoMapperProfile : Profile |
|||
{ |
|||
public MyProjectNameAutoMapperProfile() |
|||
{ |
|||
/* Create your AutoMapper object mappings here */ |
|||
} |
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
using Microsoft.AspNetCore.ResponseCompression; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Server; |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Server.Data; |
|||
using Serilog; |
|||
using Serilog.Events; |
|||
using Volo.Abp.Data; |
|||
|
|||
public class Program |
|||
{ |
|||
public async static Task<int> Main(string[] args) |
|||
{ |
|||
//<TEMPLATE-REMOVE IF-NOT='dbms:PostgreSQL'>
|
|||
// https://www.npgsql.org/efcore/release-notes/6.0.html#opting-out-of-the-new-timestamp-mapping-logic
|
|||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); |
|||
|
|||
//</TEMPLATE-REMOVE>
|
|||
var loggerConfiguration = 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()); |
|||
|
|||
if (IsMigrateDatabase(args)) |
|||
{ |
|||
loggerConfiguration.MinimumLevel.Override("Volo.Abp", LogEventLevel.Warning); |
|||
loggerConfiguration.MinimumLevel.Override("Microsoft", LogEventLevel.Warning); |
|||
} |
|||
|
|||
Log.Logger = loggerConfiguration.CreateLogger(); |
|||
|
|||
try |
|||
{ |
|||
|
|||
var builder = WebApplication.CreateBuilder(args); |
|||
builder.Host.AddAppSettingsSecretsJson() |
|||
.UseAutofac() |
|||
.UseSerilog(); |
|||
await builder.AddApplicationAsync<MyProjectNameServerModule>(); |
|||
if (IsMigrateDatabase(args)) |
|||
{ |
|||
builder.Services.AddDataMigrationEnvironment(); |
|||
} |
|||
var app = builder.Build(); |
|||
await app.InitializeApplicationAsync(); |
|||
|
|||
if (IsMigrateDatabase(args)) |
|||
{ |
|||
await app.Services.GetRequiredService<MyProjectNameDbMigrationService>().MigrateAsync(); |
|||
return 0; |
|||
} |
|||
|
|||
Log.Information("Starting MyCompanyName.MyProjectName."); |
|||
await app.RunAsync(); |
|||
return 0; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
if (ex is HostAbortedException) |
|||
{ |
|||
throw; |
|||
} |
|||
|
|||
Log.Fatal(ex, "MyCompanyName.MyProjectName terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
} |
|||
|
|||
private static bool IsMigrateDatabase(string[] args) |
|||
{ |
|||
return args.Any(x => x.Contains("--migrate-database", StringComparison.OrdinalIgnoreCase)); |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,30 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "https://localhost:44300", |
|||
"sslPort": 44300 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"https": { |
|||
"commandName": "Project", |
|||
"dotnetRunMessages": true, |
|||
"launchBrowser": true, |
|||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", |
|||
"applicationUrl": "https://localhost:44300", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
{ |
|||
"App": { |
|||
"SelfUrl": "https://localhost:44300", |
|||
"CorsOrigins": "https://*.MyProjectName.com,http://localhost:44300", |
|||
"RedirectAllowedUrls": "http://localhost:44300" |
|||
}, |
|||
"ConnectionStrings": { |
|||
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=MyProjectName;Trusted_Connection=True;TrustServerCertificate=True" |
|||
}, |
|||
"AuthServer": { |
|||
"Authority": "https://localhost:44300", |
|||
"RequireHttpsMetadata": "false", |
|||
"SwaggerClientId": "MyProjectName_Swagger", |
|||
"SwaggerClientSecret": "1q2w3e*" |
|||
}, |
|||
"StringEncryption": { |
|||
"DefaultPassPhrase": "gsKnGZ041HLL4IM8" |
|||
}, |
|||
"OpenIddict": { |
|||
"Applications": { |
|||
"MyProjectName_Blazor": { |
|||
"ClientId": "MyProjectName_Blazor", |
|||
"RootUrl": "https://localhost:44300" |
|||
}, |
|||
"MyProjectName_Swagger": { |
|||
"ClientId": "MyProjectName_Swagger", |
|||
"RootUrl": "https://localhost:44300" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"version": "1.0.0", |
|||
"name": "my-app", |
|||
"private": true, |
|||
"dependencies": { |
|||
"@abp/aspnetcore.mvc.ui.theme.leptonxlite": "~2.0.0-rc.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.WebAssembly.Server.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,8 @@ |
|||
/* Your Global Styles */ |
|||
|
|||
/* <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> */ |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "ar", |
|||
"texts": { |
|||
"Welcome_Title": "مرحبا", |
|||
"Welcome_Text": "هذا هو قالب بدء تشغيل تطبيق ذو طبقة واحدة مبسط لإطار عمل ABP.", |
|||
"Menu:Home": "الصفحة الرئيسية" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
"Welcome_Title": "Vítejte", |
|||
"Welcome_Text": "Toto je minimalistická šablona pro spuštění aplikace s jednou vrstvou pro ABP Framework.", |
|||
"Menu:Home": "Úvod" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "de", |
|||
"texts": { |
|||
"Welcome_Title": "Willkommen", |
|||
"Welcome_Text": "Dies ist eine minimalistische, einschichtige Anwendungsstartvorlage für das ABP-Framework.", |
|||
"Menu:Home": "Home" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "en-GB", |
|||
"texts": { |
|||
"Welcome_Title": "Welcome_Title", |
|||
"Welcome_Text": "This is a minimalist, single layer application startup template for the ABP Framework.", |
|||
"Menu:Home": "Home" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"Welcome_Title": "Welcome", |
|||
"Welcome_Text": "This is a minimalist, single layer application startup template for the ABP Framework.", |
|||
"Menu:Home": "Home" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "es", |
|||
"texts": { |
|||
"Welcome_Title": "Bienvenido", |
|||
"Welcome_Text": "Esta es una plantilla de inicio de aplicación minimalista de una sola capa para ABP Framework.", |
|||
"Menu:Home": "Inicio" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "fi", |
|||
"texts": { |
|||
"Welcome_Title": "Tervetuloa", |
|||
"Welcome_Text": "Tämä on minimalistinen yksikerroksinen sovelluksen käynnistysmalli ABP Frameworkille.", |
|||
"Menu:Home": "Koti" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "fr", |
|||
"texts": { |
|||
"Welcome_Title": "Bienvenue", |
|||
"Welcome_Text": "Il s'agit d'un modèle de démarrage d'application minimaliste à une seule couche pour le cadre ABP.", |
|||
"Menu:Home": "Accueil" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "hi", |
|||
"texts": { |
|||
"Welcome_Title": "स्वागत हे", |
|||
"Welcome_Text": "यह एबीपी फ्रेमवर्क के लिए एक न्यूनतम, सिंगल लेयर एप्लिकेशन स्टार्टअप टेम्प्लेट है।", |
|||
"Menu:Home": "घर" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "hu", |
|||
"texts": { |
|||
"Welcome_Title": "Üdvözlöm", |
|||
"Welcome_Text": "Ez egy minimalista, egyrétegű alkalmazásindítási sablon az ABP-keretrendszerhez.", |
|||
"Menu:Home": "Kezdőlap" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "is", |
|||
"texts": { |
|||
"Welcome_Title": "Velkomin", |
|||
"Welcome_Text": "Þetta er lægstur, eins lags ræsingarsniðmát fyrir ABP Framework.", |
|||
"Menu:Home": "Heim" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "it", |
|||
"texts": { |
|||
"Welcome_Title": "Benvenuto", |
|||
"Welcome_Text": "Questo è un modello di avvio dell'applicazione minimalista a livello singolo per ABP Framework.", |
|||
"Menu:Home": "Home" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "nl", |
|||
"texts": { |
|||
"Welcome_Title": "Welkom", |
|||
"Welcome_Text": "Dit is een minimalistische, enkellaagse applicatie-opstartsjabloon voor het ABP Framework.", |
|||
"Menu:Home": "Home" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "pl-PL", |
|||
"texts": { |
|||
"Welcome_Title": "Witaj", |
|||
"Welcome_Text": "Jest to minimalistyczny, jednowarstwowy szablon uruchamiania aplikacji dla ABP Framework.", |
|||
"Menu:Home": "Home" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
"Welcome_Title": "Seja bem-vindo!", |
|||
"Welcome_Text": "Este é um modelo de inicialização de aplicativo de camada única minimalista para o ABP Framework.", |
|||
"Menu:Home": "Principal" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "ro-RO", |
|||
"texts": { |
|||
"Welcome_Title": "Bun venit", |
|||
"Welcome_Text": "Acesta este un șablon de pornire a aplicației minimaliste, cu un singur strat, pentru Cadrul ABP.", |
|||
"Menu:Home": "Acasă" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "ru", |
|||
"texts": { |
|||
"Welcome_Title": "Bine ati venit", |
|||
"Welcome_Text": "Acesta este un șablon de pornire a aplicației minimaliste, cu un singur strat, pentru Cadrul ABP.", |
|||
"Menu:Home": "Главная" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "sk", |
|||
"texts": { |
|||
"Welcome_Title": "Vitajte", |
|||
"Welcome_Text": "Toto je minimalistická šablóna na spustenie aplikácie s jednou vrstvou pre rámec ABP.", |
|||
"Menu:Home": "Domov" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"Welcome_Title": "Dobrodošli", |
|||
"Welcome_Text": "To je minimalistična enoslojna predloga za zagon aplikacije za ABP Framework.", |
|||
"Menu:Home": "Domov" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"Welcome_Title": "Hoşgeldiniz", |
|||
"Welcome_Text": "Bu proje tek katmanlı ABP uygulamaları yapmak için bir başlangıç şablonudur.", |
|||
"Menu:Home": "Ana sayfa" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
"Welcome_Title": "Chào mừng bạn", |
|||
"Welcome_Text": "Đây là một mẫu khởi động ứng dụng lớp đơn, tối giản cho ABP Framework.", |
|||
"Menu:Home": "Trang chủ" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"Welcome_Title": "欢迎", |
|||
"Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", |
|||
"Menu:Home": "首页" |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"Welcome_Title": "歡迎", |
|||
"Welcome_Text": "這是 ABP 框架的極簡單層應用程序啟動模板.", |
|||
"Menu:Home": "首頁" |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.Localization; |
|||
|
|||
[LocalizationResourceName("MyProjectName")] |
|||
public class MyProjectNameResource |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.MultiTenancy; |
|||
|
|||
public static class MultiTenancyConsts |
|||
{ |
|||
/* Enable/disable multi-tenancy easily in a single point. |
|||
* If you will never need to multi-tenancy, you can remove |
|||
* related modules and code parts, including this file. |
|||
*/ |
|||
public const bool IsEnabled = true; |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net7.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<SupportedPlatform Include="browser" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<EmbeddedResource Include="Localization\MyProjectName\*.json" /> |
|||
<Content Remove="Localization\MyProjectName\*.json" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\..\framework\src\Volo.Abp.Validation\Volo.Abp.Validation.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="7.0.0" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,59 @@ |
|||
using MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Localization.ExceptionHandling; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Validation; |
|||
using Volo.Abp.Validation.Localization; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebAssembly.Shared; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpValidationModule) |
|||
)] |
|||
public class MyProjectNameSharedModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<MyProjectNameSharedModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources |
|||
.Add<MyProjectNameResource>("en") |
|||
.AddBaseTypes(typeof(AbpValidationResource)) |
|||
.AddVirtualJson("/Localization/MyProjectName"); |
|||
|
|||
options.DefaultResourceType = typeof(MyProjectNameResource); |
|||
|
|||
options.Languages.Add(new LanguageInfo("en", "en", "English")); |
|||
options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); |
|||
options.Languages.Add(new LanguageInfo("ar", "ar", "العربية")); |
|||
options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); |
|||
options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); |
|||
options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); |
|||
options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); |
|||
options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); |
|||
options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); |
|||
options.Languages.Add(new LanguageInfo("is", "is", "Icelandic", "is")); |
|||
options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it")); |
|||
options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); |
|||
options.Languages.Add(new LanguageInfo("ro-RO", "ro-RO", "Română")); |
|||
options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); |
|||
options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak")); |
|||
options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); |
|||
options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文")); |
|||
options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch", "de")); |
|||
options.Languages.Add(new LanguageInfo("es", "es", "Español")); |
|||
options.Languages.Add(new LanguageInfo("el", "el", "Ελληνικά")); |
|||
}); |
|||
|
|||
Configure<AbpExceptionLocalizationOptions>(options => |
|||
{ |
|||
options.MapCodeNamespace("MyProjectName", typeof(MyProjectNameResource)); |
|||
}); |
|||
} |
|||
} |
|||