mirror of https://github.com/abpframework/abp.git
442 changed files with 22750 additions and 3522 deletions
@ -0,0 +1,67 @@ |
|||||
|
# Build Command |
||||
|
|
||||
|
Building a .NET project is hard when the project references a project reference outside of the solution or even from a different GIT repository. This command builds a GIT repository and it's depending repositories or a single .NET solution File. In order ```build``` command to work, its **executing directory** or passed ```--working-directory``` parameter's directory must contain one of; |
||||
|
|
||||
|
* A .NET solution file (*.sln) |
||||
|
* abp-build-config.json |
||||
|
|
||||
|
When the executing directory (or ```--working-directory``` parameter's directory) contains a .NET solution file, ```build``` command builds all the projects in the related solution file and all project references on building project files recursively. |
||||
|
|
||||
|
When the executing directory (or ```--working-directory``` parameter's directory) contains a ```abp-build-config.json```, ```build``` command builds all changed projects form its last build and all project references on building project files recursively. |
||||
|
|
||||
|
# Build Command Config |
||||
|
|
||||
|
```abp-build-config.json``` contains properties below; |
||||
|
|
||||
|
* ```Name```: Name of the GIT repository. This can be friendly name of your GIT repository or any other unique string for the repository. |
||||
|
* ```RootPath```: Root path of the repository which contains ```.git``` folder. |
||||
|
* ```DependingRepositories```: Depending repository list of a repository. Each depending repository item contains same fields as a repository. |
||||
|
* ```IgnoredDirectories```: Relative directory paths to ignore while building a GIT repository. |
||||
|
|
||||
|
A sample ```abp-build-config.json``` looks like for a Windows OS; |
||||
|
|
||||
|
````json |
||||
|
{ |
||||
|
"Name": "main-repository", |
||||
|
"RootPath": "D:\\GitHub\\main-repository", |
||||
|
"DependingRepositories": [{ |
||||
|
"Name": "module-repository", |
||||
|
"RootPath": "D:\\GitHub\\module-repository" |
||||
|
}], |
||||
|
"IgnoredDirectories": [ |
||||
|
"utils" |
||||
|
] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
|
# Build Status |
||||
|
|
||||
|
ABP CLI stores a build status file for builds using the repository friendly names and current branch names in the; |
||||
|
|
||||
|
* ```%USERPROFILE%\.abp\build\``` for Windows. |
||||
|
* ```$HOME/.abp/build/``` for Linux/macOS. |
||||
|
|
||||
|
and uses this file when building same repository next time and only builds affected projects and decreases the total build time. A sample build status file content looks like; |
||||
|
|
||||
|
````json |
||||
|
{ |
||||
|
"RepositoryName": "main-repository", |
||||
|
"BranchName": "dev", |
||||
|
"CommitId": "84ecde8ba275aeeb14d24a87ad46a1e941adf8ba", |
||||
|
"SucceedProjects": [{ |
||||
|
"CsProjPath": "D:\\GitHub\\main-repository\\BookStore\\BookStore.Web.csproj", |
||||
|
"CommitId": "84ecde8ba275aeeb14d24a87ad46a1e941adf8ba" |
||||
|
}], |
||||
|
"DependingRepositories": [{ |
||||
|
"RepositoryName": "module-repository", |
||||
|
"BranchName": "dev", |
||||
|
"CommitId": "0598b8e45af9507fc9ba8abf304e78fc7d434e04", |
||||
|
"SucceedProjects": [{ |
||||
|
"CsProjPath": "D:\\GitHub\\module-repository\\identity-module\Identity\\Identity.Web.csproj", |
||||
|
"CommitId": "0598b8e45af9507fc9ba8abf304e78fc7d434e04" |
||||
|
}], |
||||
|
"DependingRepositories": [] |
||||
|
}] |
||||
|
} |
||||
|
```` |
||||
|
|
||||
@ -1,5 +1,28 @@ |
|||||
# 身份管理模块 |
# 身份管理模块 |
||||
|
|
||||
身份模块基于Microsoft Identity 库用于管理[组织单元](Organization-Units.md), 角色, 用户和他们的权限. |
身份模块基于Microsoft Identity库用于管理[组织单元](Organization-Units.md), 角色, 用户和他们的权限. |
||||
|
|
||||
参阅 [源码](https://github.com/abpframework/abp/tree/dev/modules/identity). 文档很快会被完善. |
参阅 [源码](https://github.com/abpframework/abp/tree/dev/modules/identity). 文档很快会被完善. |
||||
|
|
||||
|
## Identity安全日志 |
||||
|
|
||||
|
安全日志可以记录账户的一些重要的操作或者改动, 你可以在在一些功能中保存安全日志. |
||||
|
|
||||
|
你可以注入和使用 `IdentitySecurityLogManager` 或 `ISecurityLogManager` 来保存安全日志. 默认它会创建一个安全日志对象并填充常用的值. 如 `CreationTime`, `ClientIpAddress`, `BrowserInfo`, `current user/tenant`等等. 当然你可以自定义这些值. |
||||
|
|
||||
|
```cs |
||||
|
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext() |
||||
|
{ |
||||
|
Identity = "IdentityServer"; |
||||
|
Action = "ChangePassword"; |
||||
|
}); |
||||
|
``` |
||||
|
|
||||
|
通过配置 `AbpSecurityLogOptions` 来提供应用程序的名称或者禁用安全日志功能. 默认是**启用**状态. |
||||
|
|
||||
|
```cs |
||||
|
Configure<AbpSecurityLogOptions>(options => |
||||
|
{ |
||||
|
options.ApplicationName = "AbpSecurityTest"; |
||||
|
}); |
||||
|
``` |
||||
|
|||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,50 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Authentication; |
||||
|
using Microsoft.AspNetCore.Authentication.OAuth.Claims; |
||||
|
using Microsoft.AspNetCore.Authentication.OpenIdConnect; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.AspNetCore.MultiTenancy; |
||||
|
|
||||
|
namespace Microsoft.Extensions.DependencyInjection |
||||
|
{ |
||||
|
public static class AbpOpenIdConnectExtensions |
||||
|
{ |
||||
|
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder) |
||||
|
=> builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, _ => { }); |
||||
|
|
||||
|
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, Action<OpenIdConnectOptions> configureOptions) |
||||
|
=> builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, configureOptions); |
||||
|
|
||||
|
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, Action<OpenIdConnectOptions> configureOptions) |
||||
|
=> builder.AddAbpOpenIdConnect(authenticationScheme, OpenIdConnectDefaults.DisplayName, configureOptions); |
||||
|
|
||||
|
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<OpenIdConnectOptions> configureOptions) |
||||
|
{ |
||||
|
return builder.AddOpenIdConnect(authenticationScheme, displayName, options => |
||||
|
{ |
||||
|
options.ClaimActions.MapAbpClaimTypes(); |
||||
|
|
||||
|
options.Events = new OpenIdConnectEvents |
||||
|
{ |
||||
|
OnAuthorizationCodeReceived = receivedContext => |
||||
|
{ |
||||
|
var tenantKey = receivedContext.HttpContext.RequestServices |
||||
|
.GetRequiredService<IOptionsSnapshot<AbpAspNetCoreMultiTenancyOptions>>().Value.TenantKey; |
||||
|
|
||||
|
if (receivedContext.HttpContext.Request != null && |
||||
|
receivedContext.Request.Cookies.ContainsKey(tenantKey)) |
||||
|
{ |
||||
|
receivedContext.TokenEndpointRequest.SetParameter(tenantKey, |
||||
|
receivedContext.Request.Cookies[tenantKey]); |
||||
|
} |
||||
|
|
||||
|
return Task.CompletedTask; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
configureOptions?.Invoke(options); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp3.1</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.6" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.MultiTenancy\Volo.Abp.AspNetCore.MultiTenancy.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Authentication.OAuth\Volo.Abp.AspNetCore.Authentication.OAuth.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Volo.Abp.AspNetCore.Authentication.OAuth; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Authentication.OpenIdConnect |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpMultiTenancyModule), |
||||
|
typeof(AbpAspNetCoreAuthenticationOAuthModule))] |
||||
|
public class AbpAspNetCoreAuthenticationOpenIdConnectModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreComponentsWebAssemblyThemingModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreComponentsWebAssemblyBasicThemeModule : AbpModule |
||||
|
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpRouterOptions>(options => |
||||
|
{ |
||||
|
options.AdditionalAssemblies.Add(typeof(AbpAspNetCoreComponentsWebAssemblyBasicThemeModule).Assembly); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@page "/authentication/{action}" |
||||
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
||||
|
<RemoteAuthenticatorView Action="@Action" /> |
||||
|
|
||||
|
@code{ |
||||
|
[Parameter] public string Action { get; set; } |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
@using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing |
||||
|
@using Microsoft.Extensions.Options |
||||
|
@inject IOptions<AbpRouterOptions> RouterOptions |
||||
|
<CascadingAuthenticationState> |
||||
|
<Router AppAssembly="RouterOptions.Value.AppAssembly" |
||||
|
AdditionalAssemblies="RouterOptions.Value.AdditionalAssemblies"> |
||||
|
<Found Context="routeData"> |
||||
|
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"> |
||||
|
<NotAuthorized> |
||||
|
@if (!context.User.Identity.IsAuthenticated) |
||||
|
{ |
||||
|
<RedirectToLogin /> |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<p>You are not authorized to access this resource.</p> |
||||
|
} |
||||
|
</NotAuthorized> |
||||
|
</AuthorizeRouteView> |
||||
|
</Found> |
||||
|
<NotFound> |
||||
|
<LayoutView Layout="@typeof(MainLayout)"> |
||||
|
<p>Sorry, there's nothing at this address.</p> |
||||
|
</LayoutView> |
||||
|
</NotFound> |
||||
|
</Router> |
||||
|
</CascadingAuthenticationState> |
||||
@ -0,0 +1,65 @@ |
|||||
|
@using Volo.Abp.Localization |
||||
|
@using System.Globalization |
||||
|
@using System.Collections.Immutable |
||||
|
@inject ILanguageProvider LanguageProvider |
||||
|
@inject IJSRuntime JsRuntime |
||||
|
@if (_otherLanguages != null && _otherLanguages.Any()) |
||||
|
{ |
||||
|
<Dropdown> |
||||
|
<DropdownToggle Color="Color.None"> |
||||
|
@_currentLanguage.DisplayName |
||||
|
</DropdownToggle> |
||||
|
<DropdownMenu> |
||||
|
@foreach (var language in _otherLanguages) |
||||
|
{ |
||||
|
<DropdownItem Clicked="() => ChangeLanguageAsync(language)">@language.DisplayName</DropdownItem> |
||||
|
} |
||||
|
</DropdownMenu> |
||||
|
</Dropdown> |
||||
|
} |
||||
|
@code { |
||||
|
private IReadOnlyList<LanguageInfo> _otherLanguages; |
||||
|
private LanguageInfo _currentLanguage; |
||||
|
|
||||
|
protected override async Task OnInitializedAsync() |
||||
|
{ |
||||
|
var selectedLanguageName = await JsRuntime.InvokeAsync<string>( |
||||
|
"localStorage.getItem", |
||||
|
"Abp.SelectedLanguage" |
||||
|
); |
||||
|
|
||||
|
_otherLanguages = await LanguageProvider.GetLanguagesAsync(); |
||||
|
|
||||
|
if (!_otherLanguages.Any()) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (!selectedLanguageName.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
_currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == selectedLanguageName); |
||||
|
} |
||||
|
|
||||
|
if (_currentLanguage == null) |
||||
|
{ |
||||
|
_currentLanguage = _otherLanguages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name); |
||||
|
} |
||||
|
|
||||
|
if (_currentLanguage == null) |
||||
|
{ |
||||
|
_currentLanguage = _otherLanguages.FirstOrDefault(); |
||||
|
} |
||||
|
|
||||
|
_otherLanguages = _otherLanguages.Where(l => l != _currentLanguage).ToImmutableList(); |
||||
|
} |
||||
|
|
||||
|
private async Task ChangeLanguageAsync(LanguageInfo language) |
||||
|
{ |
||||
|
await JsRuntime.InvokeVoidAsync( |
||||
|
"localStorage.setItem", |
||||
|
"Abp.SelectedLanguage", language.UiCultureName |
||||
|
); |
||||
|
|
||||
|
await JsRuntime.InvokeVoidAsync("location.reload"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
||||
|
@using Volo.Abp.Users |
||||
|
@inject ICurrentUser CurrentUser |
||||
|
@inject NavigationManager Navigation |
||||
|
@inject SignOutSessionStateManager SignOutManager |
||||
|
<AuthorizeView> |
||||
|
<Authorized> |
||||
|
<Dropdown> |
||||
|
<DropdownToggle Color="Color.None"> |
||||
|
@CurrentUser.UserName |
||||
|
</DropdownToggle> |
||||
|
<DropdownMenu> |
||||
|
@if (Menu != null) |
||||
|
{ |
||||
|
@foreach (var menuItem in Menu.Items) |
||||
|
{ |
||||
|
<DropdownItem Clicked="@(() => NavigateTo(menuItem.Url))">@menuItem.DisplayName</DropdownItem> |
||||
|
} |
||||
|
} |
||||
|
<Divider /> |
||||
|
<DropdownItem Clicked="BeginSignOut">Logout</DropdownItem> |
||||
|
</DropdownMenu> |
||||
|
</Dropdown> |
||||
|
</Authorized> |
||||
|
<NotAuthorized> |
||||
|
<a class="nav-link" href="authentication/login">Log in</a> |
||||
|
</NotAuthorized> |
||||
|
</AuthorizeView> |
||||
|
@code{ |
||||
|
|
||||
|
private void NavigateTo(string uri) |
||||
|
{ |
||||
|
Navigation.NavigateTo(uri); |
||||
|
} |
||||
|
|
||||
|
private async Task BeginSignOut() |
||||
|
{ |
||||
|
await SignOutManager.SetSignOutState(); |
||||
|
NavigateTo("authentication/logout"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic |
||||
|
{ |
||||
|
public partial class LoginDisplay |
||||
|
{ |
||||
|
[Inject] protected IMenuManager MenuManager { get; set; } |
||||
|
|
||||
|
protected ApplicationMenu Menu { get; set; } |
||||
|
|
||||
|
protected override async Task OnInitializedAsync() |
||||
|
{ |
||||
|
Menu = await MenuManager.GetAsync(StandardMenus.User); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
@inherits LayoutComponentBase |
||||
|
@using Volo.Abp.Ui.Branding |
||||
|
@inject IBrandingProvider BrandingProvider |
||||
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark shadow-sm flex-column flex-md-row mb-4" id="main-navbar" style="min-height: 4rem;"> |
||||
|
<div class="container"> |
||||
|
<a class="navbar-brand" href="/">@BrandingProvider.AppName</a> |
||||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" |
||||
|
data-target="#main-navbar-collapse" aria-controls="main-navbar-collapse" |
||||
|
aria-expanded="false" aria-label="Toggle navigation"> |
||||
|
<span class="navbar-toggler-icon"></span> |
||||
|
</button> |
||||
|
<div class="collapse navbar-collapse" id="main-navbar-collapse"> |
||||
|
<ul class="navbar-nav mx-auto"> |
||||
|
<NavMenu/> |
||||
|
</ul> |
||||
|
<ul class="navbar-nav"> |
||||
|
<li class="nav-item"> |
||||
|
<LanguageSwitch/> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<LoginDisplay/> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</nav> |
||||
|
<div class="container"> |
||||
|
@Body |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@if (Menu != null) |
||||
|
{ |
||||
|
foreach (var menuItem in Menu.Items) |
||||
|
{ |
||||
|
<NavMenuItem MenuItem="@menuItem" /> |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Components; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Themes.Basic |
||||
|
{ |
||||
|
public partial class NavMenu |
||||
|
{ |
||||
|
[Inject] protected IMenuManager MenuManager { get; set; } |
||||
|
|
||||
|
protected ApplicationMenu Menu { get; set; } |
||||
|
|
||||
|
private bool collapseNavMenu = true; |
||||
|
|
||||
|
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; |
||||
|
|
||||
|
protected override async Task OnInitializedAsync() |
||||
|
{ |
||||
|
Menu = await MenuManager.GetAsync(StandardMenus.Main); |
||||
|
} |
||||
|
|
||||
|
private void ToggleNavMenu() |
||||
|
{ |
||||
|
collapseNavMenu = !collapseNavMenu; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
@using Volo.Abp.UI.Navigation |
||||
|
@{ |
||||
|
var elementId = MenuItem.ElementId ?? "MenuItem_" + MenuItem.Name.Replace(".", "_"); |
||||
|
var cssClass = string.IsNullOrEmpty(MenuItem.CssClass) ? string.Empty : MenuItem.CssClass; |
||||
|
var url = string.IsNullOrEmpty(MenuItem.Url) ? "#" : MenuItem.Url; |
||||
|
} |
||||
|
@if (MenuItem.IsLeaf) |
||||
|
{ |
||||
|
if (MenuItem.Url != null) |
||||
|
{ |
||||
|
<li class="nav-item @cssClass" disabled="@MenuItem.IsDisabled"> |
||||
|
<NavLink class="nav-link" href="@url" id="@elementId"> |
||||
|
@if (MenuItem.Icon != null) |
||||
|
{ |
||||
|
if (MenuItem.Icon.StartsWith("fa")) |
||||
|
{ |
||||
|
<i class="@MenuItem.Icon"></i> |
||||
|
} |
||||
|
} |
||||
|
@MenuItem.DisplayName |
||||
|
</NavLink> |
||||
|
</li> |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
<li class="nav-item"> |
||||
|
<div class="dropdown"> |
||||
|
<a class="nav-link dropdown-toggle" href="#" id="@elementId" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
||||
|
@if (MenuItem.Icon != null) |
||||
|
{ |
||||
|
if (MenuItem.Icon.StartsWith("fa")) |
||||
|
{ |
||||
|
<i class="@MenuItem.Icon"></i> |
||||
|
} |
||||
|
} |
||||
|
@MenuItem.DisplayName |
||||
|
</a> |
||||
|
<div class="dropdown-menu border-0 shadow-sm" aria-labelledby="@elementId"> |
||||
|
@foreach (var childMenuItem in MenuItem.Items) |
||||
|
{ |
||||
|
<NavMenuItem MenuItem="@childMenuItem" /> |
||||
|
} |
||||
|
</div> |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
} |
||||
|
@code { |
||||
|
[Parameter] |
||||
|
public ApplicationMenuItem MenuItem { get; set; } |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
@inject NavigationManager Navigation |
||||
|
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication |
||||
|
@code { |
||||
|
protected override void OnInitialized() |
||||
|
{ |
||||
|
Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
@using System.Net.Http |
||||
|
@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.WebAssembly |
||||
|
@using Blazorise |
||||
|
@using Blazorise.DataGrid |
||||
@ -0,0 +1,16 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<RazorLangVersion>3.0</RazorLangVersion> |
||||
|
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme</PackageId> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly.Theming\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,105 @@ |
|||||
|
|
||||
|
#main-navbar-tools a.dropdown-toggle { |
||||
|
text-decoration: none; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
.navbar .dropdown-submenu { |
||||
|
position: relative; |
||||
|
} |
||||
|
.navbar .dropdown-menu { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
.navbar .dropdown-menu a { |
||||
|
font-size: .9em; |
||||
|
padding: 10px 15px; |
||||
|
display: block; |
||||
|
min-width: 210px; |
||||
|
text-align: left; |
||||
|
border-radius: 0.25rem; |
||||
|
min-height: 44px; |
||||
|
} |
||||
|
.navbar .dropdown-submenu a::after { |
||||
|
transform: rotate(-90deg); |
||||
|
position: absolute; |
||||
|
right: 16px; |
||||
|
top: 18px; |
||||
|
} |
||||
|
.navbar .dropdown-submenu .dropdown-menu { |
||||
|
top: 0; |
||||
|
left: 100%; |
||||
|
} |
||||
|
|
||||
|
.card-header .btn { |
||||
|
padding: 2px 6px; |
||||
|
} |
||||
|
.card-header h5 { |
||||
|
margin: 0; |
||||
|
} |
||||
|
.container > .card { |
||||
|
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; |
||||
|
} |
||||
|
|
||||
|
@media screen and (min-width: 768px) { |
||||
|
.navbar .dropdown:hover > .dropdown-menu { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
.navbar .dropdown-submenu:hover > .dropdown-menu { |
||||
|
display: block; |
||||
|
} |
||||
|
} |
||||
|
.input-validation-error { |
||||
|
border-color: #dc3545; |
||||
|
} |
||||
|
.field-validation-error { |
||||
|
font-size: 0.8em; |
||||
|
} |
||||
|
|
||||
|
.dataTables_scrollBody { |
||||
|
min-height: 248px; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_wrapper div.dataTables_info { |
||||
|
padding-top: 11px; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
div.dataTables_wrapper div.dataTables_length label { |
||||
|
padding-top: 10px; |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.rtl .dropdown-menu-right { |
||||
|
right: auto; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.rtl .dropdown-menu-right a { |
||||
|
text-align: right; |
||||
|
} |
||||
|
|
||||
|
.rtl .navbar .dropdown-menu a { |
||||
|
text-align: right; |
||||
|
} |
||||
|
.rtl .navbar .dropdown-submenu .dropdown-menu { |
||||
|
top: 0; |
||||
|
left: auto; |
||||
|
right: 100%; |
||||
|
} |
||||
|
|
||||
|
/* TEMP */ |
||||
|
|
||||
|
.navbar-dark .navbar-nav .nav-link { |
||||
|
color: #000 !important; |
||||
|
} |
||||
|
|
||||
|
.navbar-nav > .nav-item > .nav-link, |
||||
|
.navbar-nav > .nav-item > .dropdown > .nav-link { |
||||
|
color: #fff !important; |
||||
|
} |
||||
|
|
||||
|
.navbar-nav>.nav-item>div>button{ |
||||
|
color:#fff; |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
$(function () { |
||||
|
$('.dropdown-menu a.dropdown-toggle').on('click', function (e) { |
||||
|
if (!$(this).next().hasClass('show')) { |
||||
|
$(this).parents('.dropdown-menu').first().find('.show').removeClass("show"); |
||||
|
} |
||||
|
|
||||
|
var $subMenu = $(this).next(".dropdown-menu"); |
||||
|
$subMenu.toggleClass('show'); |
||||
|
|
||||
|
$(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function (e) { |
||||
|
$('.dropdown-submenu .show').removeClass("show"); |
||||
|
}); |
||||
|
|
||||
|
return false; |
||||
|
}); |
||||
|
}); |
||||
@ -0,0 +1,17 @@ |
|||||
|
using Volo.Abp.BlazoriseUI; |
||||
|
using Volo.Abp.Http.Client.IdentityModel.WebAssembly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.UI.Navigation; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpBlazoriseUIModule), |
||||
|
typeof(AbpHttpClientIdentityModelWebAssemblyModule), |
||||
|
typeof(AbpUiNavigationModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreComponentsWebAssemblyThemingModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing |
||||
|
{ |
||||
|
public class AbpRouterOptions |
||||
|
{ |
||||
|
public Assembly AppAssembly { get; set; } |
||||
|
|
||||
|
public RouterAssemblyList AdditionalAssemblies { get; } |
||||
|
|
||||
|
public AbpRouterOptions() |
||||
|
{ |
||||
|
AdditionalAssemblies = new RouterAssemblyList(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Routing |
||||
|
{ |
||||
|
public class RouterAssemblyList : List<Assembly> |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<RazorLangVersion>3.0</RazorLangVersion> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.BlazoriseUI\Volo.Abp.BlazoriseUI.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Http.Client.IdentityModel.WebAssembly\Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.UI.Navigation\Volo.Abp.UI.Navigation.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,51 @@ |
|||||
|
using System; |
||||
|
using System.Reflection; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.Configuration; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting |
||||
|
{ |
||||
|
public static class AbpWebAssemblyHostBuilderExtensions |
||||
|
{ |
||||
|
public static IAbpApplicationWithExternalServiceProvider AddApplication<TStartupModule>( |
||||
|
[NotNull] this WebAssemblyHostBuilder builder, |
||||
|
Action<AbpWebAssemblyApplicationCreationOptions> options) |
||||
|
where TStartupModule : IAbpModule |
||||
|
{ |
||||
|
Check.NotNull(builder, nameof(builder)); |
||||
|
|
||||
|
builder.Services.AddSingleton<IConfiguration>(builder.Configuration); |
||||
|
builder.Services.AddSingleton(builder); |
||||
|
|
||||
|
var application = builder.Services.AddApplication<TStartupModule>(opts => |
||||
|
{ |
||||
|
options?.Invoke(new AbpWebAssemblyApplicationCreationOptions(builder, opts)); |
||||
|
}); |
||||
|
|
||||
|
return application; |
||||
|
} |
||||
|
|
||||
|
public static async Task InitializeAsync( |
||||
|
[NotNull] this IAbpApplicationWithExternalServiceProvider application, |
||||
|
[NotNull] IServiceProvider serviceProvider) |
||||
|
{ |
||||
|
Check.NotNull(application, nameof(application)); |
||||
|
Check.NotNull(serviceProvider, nameof(serviceProvider)); |
||||
|
|
||||
|
application.Initialize(serviceProvider); |
||||
|
|
||||
|
using (var scope = serviceProvider.CreateScope()) |
||||
|
{ |
||||
|
await scope.ServiceProvider |
||||
|
.GetRequiredService<ICachedApplicationConfigurationClient>() |
||||
|
.InitializeAsync(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.AspNetCore.Components.WebAssembly</AssemblyName> |
||||
|
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.Client.Common\Volo.Abp.AspNetCore.Mvc.Client.Common.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.UI\Volo.Abp.UI.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.1" /> |
||||
|
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="3.1.6" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,26 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.Http.Client; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.UI; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAspNetCoreMvcClientCommonModule), |
||||
|
typeof(AbpUiModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreComponentsWebAssemblyModule : AbpModule |
||||
|
{ |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
PreConfigure<AbpHttpClientBuilderOptions>(options => |
||||
|
{ |
||||
|
options.ProxyClientBuildActions.Add((_, builder) => |
||||
|
{ |
||||
|
builder.AddHttpMessageHandler<AbpBlazorClientHttpMessageHandler>(); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
using System; |
||||
|
using System.Net.Http; |
||||
|
using System.Net.Http.Headers; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.JSInterop; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class AbpBlazorClientHttpMessageHandler : DelegatingHandler, ITransientDependency |
||||
|
{ |
||||
|
private readonly IJSRuntime _jsRuntime; |
||||
|
|
||||
|
public AbpBlazorClientHttpMessageHandler(IJSRuntime jsRuntime) |
||||
|
{ |
||||
|
_jsRuntime = jsRuntime; |
||||
|
} |
||||
|
|
||||
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) |
||||
|
{ |
||||
|
await SetLanguageAsync(request, cancellationToken); |
||||
|
|
||||
|
return await base.SendAsync(request, cancellationToken); |
||||
|
} |
||||
|
|
||||
|
private async Task SetLanguageAsync(HttpRequestMessage request, CancellationToken cancellationToken) |
||||
|
{ |
||||
|
var selectedLanguage = await _jsRuntime.InvokeAsync<string>( |
||||
|
"localStorage.getItem", |
||||
|
cancellationToken, |
||||
|
"Abp.SelectedLanguage" |
||||
|
); |
||||
|
|
||||
|
if (!selectedLanguage.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
request.Headers.AcceptLanguage.Clear(); |
||||
|
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(selectedLanguage)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class AbpWebAssemblyApplicationCreationOptions |
||||
|
{ |
||||
|
public WebAssemblyHostBuilder HostBuilder { get; } |
||||
|
|
||||
|
public AbpApplicationCreationOptions ApplicationCreationOptions { get; } |
||||
|
|
||||
|
public AbpWebAssemblyApplicationCreationOptions( |
||||
|
WebAssemblyHostBuilder hostBuilder, |
||||
|
AbpApplicationCreationOptions applicationCreationOptions) |
||||
|
{ |
||||
|
HostBuilder = hostBuilder; |
||||
|
ApplicationCreationOptions = applicationCreationOptions; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class ApplicationConfigurationCache : ISingletonDependency |
||||
|
{ |
||||
|
protected ApplicationConfigurationDto Configuration { get; set; } |
||||
|
|
||||
|
public virtual ApplicationConfigurationDto Get() |
||||
|
{ |
||||
|
return Configuration; |
||||
|
} |
||||
|
|
||||
|
internal void Set(ApplicationConfigurationDto configuration) |
||||
|
{ |
||||
|
Configuration = configuration; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public interface IUiMessageService |
||||
|
{ |
||||
|
Task InfoAsync(string message, string title = null); |
||||
|
|
||||
|
Task SuccessAsync(string message, string title = null); |
||||
|
|
||||
|
Task WarnAsync(string message, string title = null); |
||||
|
|
||||
|
Task ErrorAsync(string message, string title = null); |
||||
|
|
||||
|
Task<bool> ConfirmAsync(string message, string title = null); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.JSInterop; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
//TODO: Implement with sweetalert in a new package
|
||||
|
public class UiMessageService : IUiMessageService, ITransientDependency |
||||
|
{ |
||||
|
protected IJSRuntime JsRuntime { get; } |
||||
|
|
||||
|
public UiMessageService(IJSRuntime jsRuntime) |
||||
|
{ |
||||
|
JsRuntime = jsRuntime; |
||||
|
} |
||||
|
|
||||
|
public async Task InfoAsync(string message, string title = null) |
||||
|
{ |
||||
|
await JsRuntime.InvokeVoidAsync("alert", message); |
||||
|
} |
||||
|
|
||||
|
public async Task SuccessAsync(string message, string title = null) |
||||
|
{ |
||||
|
await JsRuntime.InvokeVoidAsync("alert", message); |
||||
|
} |
||||
|
|
||||
|
public async Task WarnAsync(string message, string title = null) |
||||
|
{ |
||||
|
await JsRuntime.InvokeVoidAsync("alert", message); |
||||
|
} |
||||
|
|
||||
|
public async Task ErrorAsync(string message, string title = null) |
||||
|
{ |
||||
|
await JsRuntime.InvokeVoidAsync("alert", message); |
||||
|
} |
||||
|
|
||||
|
public async Task<bool> ConfirmAsync(string message, string title = null) |
||||
|
{ |
||||
|
return await JsRuntime.InvokeAsync<bool>("confirm", message); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client.DynamicProxying; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicationConfigurationClient, ITransientDependency |
||||
|
{ |
||||
|
protected IHttpClientProxy<IAbpApplicationConfigurationAppService> Proxy { get; } |
||||
|
|
||||
|
protected ApplicationConfigurationCache Cache { get; } |
||||
|
|
||||
|
public WebAssemblyCachedApplicationConfigurationClient( |
||||
|
IHttpClientProxy<IAbpApplicationConfigurationAppService> proxy, |
||||
|
ApplicationConfigurationCache cache) |
||||
|
{ |
||||
|
Proxy = proxy; |
||||
|
Cache = cache; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task InitializeAsync() |
||||
|
{ |
||||
|
Cache.Set(await Proxy.Service.GetAsync()); |
||||
|
} |
||||
|
|
||||
|
public virtual Task<ApplicationConfigurationDto> GetAsync() |
||||
|
{ |
||||
|
return Task.FromResult(GetConfigurationByChecking()); |
||||
|
} |
||||
|
|
||||
|
public virtual ApplicationConfigurationDto Get() |
||||
|
{ |
||||
|
return GetConfigurationByChecking(); |
||||
|
} |
||||
|
|
||||
|
private ApplicationConfigurationDto GetConfigurationByChecking() |
||||
|
{ |
||||
|
var configuration = Cache.Get(); |
||||
|
if (configuration == null) |
||||
|
{ |
||||
|
throw new AbpException( |
||||
|
$"{nameof(WebAssemblyCachedApplicationConfigurationClient)} should be initialized before using it."); |
||||
|
} |
||||
|
|
||||
|
return configuration; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Security.Claims; |
||||
|
using Volo.Abp.AspNetCore.Mvc.Client; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class WebAssemblyCurrentPrincipalAccessor : CurrentPrincipalAccessorBase, ITransientDependency |
||||
|
{ |
||||
|
protected ICachedApplicationConfigurationClient ConfigurationClient { get; } |
||||
|
|
||||
|
public WebAssemblyCurrentPrincipalAccessor( |
||||
|
ICachedApplicationConfigurationClient configurationClient) |
||||
|
{ |
||||
|
ConfigurationClient = configurationClient; |
||||
|
} |
||||
|
|
||||
|
protected override ClaimsPrincipal GetClaimsPrincipal() |
||||
|
{ |
||||
|
var configuration = ConfigurationClient.Get(); |
||||
|
|
||||
|
var claims = new List<Claim>(); |
||||
|
|
||||
|
if (!configuration.CurrentUser.UserName.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.UserName,configuration.CurrentUser.UserName)); |
||||
|
} |
||||
|
|
||||
|
if (!configuration.CurrentUser.Email.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.Email,configuration.CurrentUser.Email)); |
||||
|
} |
||||
|
|
||||
|
if (configuration.CurrentUser.Id != null) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.UserId,configuration.CurrentUser.Id.ToString())); |
||||
|
} |
||||
|
|
||||
|
if (configuration.CurrentUser.TenantId != null) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.TenantId,configuration.CurrentUser.TenantId.ToString())); |
||||
|
} |
||||
|
else if (configuration.CurrentTenant.Id != null) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.TenantId,configuration.CurrentTenant.Id.ToString())); |
||||
|
} |
||||
|
|
||||
|
foreach (var role in configuration.CurrentUser.Roles) |
||||
|
{ |
||||
|
claims.Add(new Claim(AbpClaimTypes.Role, role)); |
||||
|
} |
||||
|
|
||||
|
return new ClaimsPrincipal(new ClaimsIdentity(claims)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.AspNetCore.Mvc.MultiTenancy; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client.DynamicProxying; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
using Volo.Abp.Threading; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Components.WebAssembly |
||||
|
{ |
||||
|
public class WebAssemblyRemoteTenantStore : ITenantStore, ITransientDependency |
||||
|
{ |
||||
|
protected IHttpClientProxy<IAbpTenantAppService> Proxy { get; } |
||||
|
|
||||
|
public WebAssemblyRemoteTenantStore( |
||||
|
IHttpClientProxy<IAbpTenantAppService> proxy) |
||||
|
{ |
||||
|
Proxy = proxy; |
||||
|
} |
||||
|
|
||||
|
public async Task<TenantConfiguration> FindAsync(string name) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name)); |
||||
|
} |
||||
|
|
||||
|
public async Task<TenantConfiguration> FindAsync(Guid id) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id)); |
||||
|
} |
||||
|
|
||||
|
public TenantConfiguration Find(string name) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return AsyncHelper.RunSync(async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByNameAsync(name))); |
||||
|
} |
||||
|
|
||||
|
public TenantConfiguration Find(Guid id) |
||||
|
{ |
||||
|
//TODO: Cache
|
||||
|
|
||||
|
return AsyncHelper.RunSync(async () => CreateTenantConfiguration(await Proxy.Service.FindTenantByIdAsync(id))); |
||||
|
} |
||||
|
|
||||
|
protected virtual TenantConfiguration CreateTenantConfiguration(FindTenantResultDto tenantResultDto) |
||||
|
{ |
||||
|
if (!tenantResultDto.Success || tenantResultDto.TenantId == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new TenantConfiguration(tenantResultDto.TenantId.Value, tenantResultDto.Name); |
||||
|
} |
||||
|
|
||||
|
protected virtual string CreateCacheKey(string tenantName) |
||||
|
{ |
||||
|
return $"RemoteTenantStore_Name_{tenantName}"; |
||||
|
} |
||||
|
|
||||
|
protected virtual string CreateCacheKey(Guid tenantId) |
||||
|
{ |
||||
|
return $"RemoteTenantStore_Id_{tenantId:N}"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System.Linq; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Volo.Abp.MultiTenancy; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.MultiTenancy |
||||
|
{ |
||||
|
public class FormTenantResolveContributor : HttpTenantResolveContributorBase |
||||
|
{ |
||||
|
public const string ContributorName = "Form"; |
||||
|
|
||||
|
public override string Name => ContributorName; |
||||
|
|
||||
|
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext) |
||||
|
{ |
||||
|
if (httpContext.Request == null || !httpContext.Request.Form.Any()) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return httpContext.Request.Form[context.GetAbpAspNetCoreMultiTenancyOptions().TenantKey]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,24 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.AspNetCore.Mvc.Client.Common</AssemblyName> |
||||
|
<PackageId>Volo.Abp.AspNetCore.Mvc.Client.Common</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.Contracts\Volo.Abp.AspNetCore.Mvc.Contracts.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Caching\Volo.Abp.Caching.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Http.Client\Volo.Abp.Http.Client.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,33 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Caching; |
||||
|
using Volo.Abp.Http.Client; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.AspNetCore.Mvc.Client |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpHttpClientModule), |
||||
|
typeof(AbpAspNetCoreMvcContractsModule), |
||||
|
typeof(AbpCachingModule), |
||||
|
typeof(AbpLocalizationModule) |
||||
|
)] |
||||
|
public class AbpAspNetCoreMvcClientCommonModule : AbpModule |
||||
|
{ |
||||
|
public const string RemoteServiceName = "AbpMvcClient"; |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddHttpClientProxies( |
||||
|
typeof(AbpAspNetCoreMvcContractsModule).Assembly, |
||||
|
RemoteServiceName, |
||||
|
asDefaultServices: false |
||||
|
); |
||||
|
|
||||
|
Configure<AbpLocalizationOptions>(options => |
||||
|
{ |
||||
|
options.GlobalContributors.Add<RemoteLocalizationContributor>(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,33 +1,11 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
using Volo.Abp.Modularity; |
||||
using Volo.Abp.Caching; |
|
||||
using Volo.Abp.Http.Client; |
|
||||
using Volo.Abp.Localization; |
|
||||
using Volo.Abp.Modularity; |
|
||||
|
|
||||
namespace Volo.Abp.AspNetCore.Mvc.Client |
namespace Volo.Abp.AspNetCore.Mvc.Client |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(AbpHttpClientModule), |
typeof(AbpAspNetCoreMvcClientCommonModule) |
||||
typeof(AbpAspNetCoreMvcContractsModule), |
|
||||
typeof(AbpCachingModule), |
|
||||
typeof(AbpLocalizationModule) |
|
||||
)] |
)] |
||||
public class AbpAspNetCoreMvcClientModule : AbpModule |
public class AbpAspNetCoreMvcClientModule : AbpModule |
||||
{ |
{ |
||||
public const string RemoteServiceName = "AbpMvcClient"; |
|
||||
|
|
||||
public override void ConfigureServices(ServiceConfigurationContext context) |
|
||||
{ |
|
||||
context.Services.AddHttpClientProxies( |
|
||||
typeof(AbpAspNetCoreMvcContractsModule).Assembly, |
|
||||
RemoteServiceName, |
|
||||
asDefaultServices: false |
|
||||
); |
|
||||
|
|
||||
Configure<AbpLocalizationOptions>(options => |
|
||||
{ |
|
||||
options.GlobalContributors.Add<RemoteLocalizationContributor>(); |
|
||||
}); |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
||||
|
<xs:element name="Weavers"> |
||||
|
<xs:complexType> |
||||
|
<xs:all> |
||||
|
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
||||
|
<xs:complexType> |
||||
|
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:all> |
||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
||||
|
<xs:annotation> |
||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
||||
|
</xs:annotation> |
||||
|
</xs:attribute> |
||||
|
</xs:complexType> |
||||
|
</xs:element> |
||||
|
</xs:schema> |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System; |
||||
|
using Autofac; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting |
||||
|
{ |
||||
|
public static class AbpWebAssemblyApplicationCreationOptionsAutofacExtensions |
||||
|
{ |
||||
|
public static void UseAutofac( |
||||
|
[NotNull] this AbpWebAssemblyApplicationCreationOptions options, |
||||
|
[CanBeNull] Action<ContainerBuilder> configure = null) |
||||
|
{ |
||||
|
options.HostBuilder.Services.AddAutofacServiceProviderFactory(); |
||||
|
options.HostBuilder.ConfigureContainer( |
||||
|
options.HostBuilder.Services.GetSingletonInstance<IServiceProviderFactory<ContainerBuilder>>(), |
||||
|
configure |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netstandard2.1</TargetFramework> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.AspNetCore.Components.WebAssembly\Volo.Abp.AspNetCore.Components.WebAssembly.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,14 @@ |
|||||
|
using Volo.Abp.AspNetCore.Components.WebAssembly; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
|
namespace Volo.Abp.Autofac.WebAssembly |
||||
|
{ |
||||
|
[DependsOn( |
||||
|
typeof(AbpAutofacModule), |
||||
|
typeof(AbpAspNetCoreComponentsWebAssemblyModule) |
||||
|
)] |
||||
|
public class AbpAutofacWebAssemblyModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
||||
|
<ConfigureAwait ContinueOnCapturedContext="false" /> |
||||
|
</Weavers> |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue