Browse Source

Merge pull request #3 from abpframework/master

udpate fork
pull/1162/head
Nokecy 7 years ago
committed by GitHub
parent
commit
753278103b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs
  2. 2
      abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml
  3. 4
      abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/HomePageLayout.cshtml
  4. 4
      abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Layout.cshtml
  5. 4
      abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/LayoutEmpty.cshtml
  6. 4
      abp_io/src/Volo.AbpWebSite.Web/Pages/Templates.cshtml
  7. 1
      abp_io/src/Volo.AbpWebSite.Web/Templates/MvcApplicationTemplate.cs
  8. 20
      abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/ProjectBuildContextExtensions.cs
  9. 17
      abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/ProjectBuildPipelineStep.cs
  10. 39
      abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/Steps/NugetReferenceReplaceStep.cs
  11. 2
      abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/Steps/RemoveProjectFromSolutionStep.cs
  12. 8
      abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/Steps/SwitchEntityFrameworkCoreToMongoDbStep.cs
  13. 2
      build-all.ps1
  14. 2
      common.props
  15. 2
      docs/en/Contribution/Index.md
  16. 2
      docs/en/Dependency-Injection.md
  17. 10
      docs/en/Getting-Started-AspNetCore-MVC-Template.md
  18. 14
      docs/en/Multi-Tenancy.md
  19. 6
      docs/en/Tutorials/AspNetCore-Mvc/Part-I.md
  20. 2
      docs/en/Tutorials/AspNetCore-Mvc/Part-III.md
  21. BIN
      docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png
  22. BIN
      docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v2.png
  23. BIN
      docs/en/images/bookstore-visual-studio-solution-v2.png
  24. BIN
      docs/en/images/pcm-update-database-v2.png
  25. 54
      docs/zh-Hans/Blog-Posts/2019-02-22/Post.md
  26. BIN
      docs/zh-Hans/Blog-Posts/2019-02-22/scott-and-jon.png
  27. 20
      docs/zh-Hans/Getting-Started-AspNetCore-Application.md
  28. 10
      docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md
  29. 14
      docs/zh-Hans/Multi-Tenancy.md
  30. 1433
      docs/zh-Hans/Samples/Microservice-Demo.md
  31. 6
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md
  32. 1
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md
  33. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png
  34. BIN
      docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v2.png
  35. BIN
      docs/zh-Hans/images/bookstore-visual-studio-solution-v2.png
  36. BIN
      docs/zh-Hans/images/microservice-sample-authserver-home.png
  37. BIN
      docs/zh-Hans/images/microservice-sample-authserver-login.png
  38. BIN
      docs/zh-Hans/images/microservice-sample-backend-ui-permissions.png
  39. BIN
      docs/zh-Hans/images/microservice-sample-backend-ui.png
  40. BIN
      docs/zh-Hans/images/microservice-sample-blogservice-permission-in-database.png
  41. BIN
      docs/zh-Hans/images/microservice-sample-diagram-2.png
  42. BIN
      docs/zh-Hans/images/microservice-sample-kibana-1.png
  43. BIN
      docs/zh-Hans/images/microservice-sample-kibana-2.png
  44. BIN
      docs/zh-Hans/images/microservice-sample-product-module-in-solution.png
  45. BIN
      docs/zh-Hans/images/microservice-sample-public-product-list.png
  46. BIN
      docs/zh-Hans/images/microservice-sample-solution.png
  47. BIN
      docs/zh-Hans/images/pcm-update-database-v2.png
  48. 21
      framework/Volo.Abp.sln
  49. 2
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo.Abp.AspNetCore.MultiTenancy.csproj
  50. 2
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs
  51. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs
  52. 16
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs
  53. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs
  54. 39
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpContextTenantResolveResultAccessor.cs
  55. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs
  56. 51
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
  57. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs
  58. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs
  59. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs
  60. 23
      framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLanguageProvider.cs
  61. 9
      framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationFeatureConfigurationDto.cs
  62. 5
      framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs
  63. 3
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs
  64. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/tenant-switch.js
  65. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj
  66. 9
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/AbpAspNetCoreMvcUiMultiTenancyModule.cs
  67. 17
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml
  68. 51
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/TenantSwitchViewComponent.cs
  69. 8
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json
  70. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json
  71. 21
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/MultiTenancyToolbarContributor.cs
  72. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs
  73. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Menu/Default.cshtml
  74. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Menu/_MenuItem.cshtml
  75. 34
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml
  76. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml
  77. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml
  78. 1
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj
  79. 3
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs
  80. 17
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js
  81. 0
      framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/IPageLayout.cs
  82. 15
      framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Http/AbpFormFileExtensions.cs
  83. 3
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs
  84. 19
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
  85. 1
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs
  86. 2
      framework/src/Volo.Abp.Auditing/Volo.Abp.Auditing.csproj
  87. 2
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingModule.cs
  88. 6
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditLogActionInfo.cs
  89. 7
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditLogInfo.cs
  90. 15
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs
  91. 12
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs
  92. 13
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityChangeInfo.cs
  93. 6
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityPropertyChangeInfo.cs
  94. 14
      framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs
  95. 1
      framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj
  96. 4
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs
  97. 2
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs
  98. 6
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs
  99. 23
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs
  100. 19
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs

17
abp_io/src/Volo.AbpWebSite.Web/AbpWebSiteWebModule.cs

@ -1,5 +1,4 @@
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@ -14,7 +13,6 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theming;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Autofac;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
@ -69,7 +67,6 @@ namespace Volo.AbpWebSite
Configure<BlogFileOptions>(options =>
{
options.FileUploadLocalFolder = Path.Combine(hostingEnvironment.WebRootPath, "files");
options.FileUploadUrlRoot = "/files/";
});
}
@ -183,18 +180,8 @@ namespace Volo.AbpWebSite
AsyncHelper.RunSync(async () =>
{
await scope.ServiceProvider
.GetRequiredService<IIdentityDataSeeder>()
.SeedAsync(
"1q2w3E*"
);
await scope.ServiceProvider
.GetRequiredService<IPermissionDataSeeder>()
.SeedAsync(
RolePermissionValueProvider.ProviderName,
"admin",
IdentityPermissions.GetAll().Union(BloggingPermissions.GetAll())
);
.GetRequiredService<IDataSeeder>()
.SeedAsync();
});
}
}

2
abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Components/Header/Default.cshtml

@ -23,7 +23,7 @@
<a class="nav-link" href="/blog/abp/">Blog</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://github.com/abpframework/abp/" target="_blank">Github</a>
<a class="nav-link" href="https://github.com/abpframework/abp/" target="_blank">GitHub</a>
</li>
<li class="for-mobile">
<button type="button" class="close close-mmenu" aria-label="Close">

4
abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/HomePageLayout.cshtml

@ -17,7 +17,7 @@
<title>@(ViewBag.Title == null ? "abp.io" : ViewBag.Title)</title>
@await Component.InvokeAsync(typeof(StandardMetaViewComponent))
<abp-style-bundle name="@AbpIoBundles.Styles.Global" />
@RenderSection("styles", false)
@await RenderSectionAsync("styles", false)
</head>
<body>
@ -47,7 +47,7 @@
gtag('config', 'UA-49982725-4');
</script>
@RenderSection("scripts", false)
@await RenderSectionAsync("scripts", false)
</body>
</html>

4
abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/Layout.cshtml

@ -17,7 +17,7 @@
<title>@(ViewBag.Title == null ? "abp.io" : ViewBag.Title)</title>
@await Component.InvokeAsync(typeof(StandardMetaViewComponent))
<abp-style-bundle name="@AbpIoBundles.Styles.Global" />
@RenderSection("styles", false)
@await RenderSectionAsync("styles", false)
</head>
<body>
@ -58,7 +58,7 @@
gtag('config', 'UA-49982725-4');
</script>
@RenderSection("scripts", false)
@await RenderSectionAsync("scripts", false)
</body>
</html>

4
abp_io/src/Volo.AbpWebSite.Web/Pages/Shared/LayoutEmpty.cshtml

@ -18,7 +18,7 @@
<title>@(ViewBag.Title == null ? "abp.io" : ViewBag.Title)</title>
@await Component.InvokeAsync(typeof(StandardMetaViewComponent))
<abp-style-bundle name="@StandardBundles.Styles.Global" />
@RenderSection("styles", false)
@await RenderSectionAsync("styles", false)
</head>
<body class="abp-empty-layout">
@ -41,7 +41,7 @@
gtag('config', 'UA-49982725-4');
</script>
@RenderSection("scripts", false)
@await RenderSectionAsync("scripts", false)
</body>
</html>

4
abp_io/src/Volo.AbpWebSite.Web/Pages/Templates.cshtml

@ -14,7 +14,7 @@
@using (Html.BeginForm(FormMethod.Post))
{
<div class="row border">
<div class="col p-5 ">
<div class="col-lg-7 p-5 ">
<h2>
<span class="text-primary">Create</span>
<span class="text-success">New Project</span>
@ -64,7 +64,7 @@
</div>
</div>
<div class="col-md-5 bg-light p-5">
<div class="col-lg-5 bg-light p-5">
<h4>The Startup Project</h4>
<p>See <a href="/documents/abp/latest/Getting-Started-AspNetCore-MVC-Template" target="_blank">the documentation</a> to understand how to run the downloaded project.</p>

1
abp_io/src/Volo.AbpWebSite.Web/Templates/MvcApplicationTemplate.cs

@ -37,6 +37,7 @@ namespace Volo.AbpWebSite.Templates
if (context.Request.DatabaseProvider != DatabaseProvider.EntityFrameworkCore)
{
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.EntityFrameworkCore"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Application.Tests", projectFolderPath: "test/MyCompanyName.MyProjectName.Application.Tests"));
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.Web.Tests", projectFolderPath: "test/MyCompanyName.MyProjectName.Web.Tests"));
}

20
abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/ProjectBuildContextExtensions.cs

@ -0,0 +1,20 @@
using System;
using System.Linq;
using Volo.Utils.SolutionTemplating.Files;
namespace Volo.Utils.SolutionTemplating.Building
{
public static class ProjectBuildContextExtensions
{
public static FileEntry GetFile(this ProjectBuildContext context, string filePath)
{
var file = context.Files.FirstOrDefault(f => f.Name == filePath);
if (file == null)
{
throw new ApplicationException("Could not find file: " + filePath);
}
return file;
}
}
}

17
abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/ProjectBuildPipelineStep.cs

@ -1,22 +1,7 @@
using System;
using System.Linq;
using Volo.Utils.SolutionTemplating.Files;
namespace Volo.Utils.SolutionTemplating.Building
namespace Volo.Utils.SolutionTemplating.Building
{
public abstract class ProjectBuildPipelineStep
{
public abstract void Execute(ProjectBuildContext context);
protected FileEntry GetFile(ProjectBuildContext context, string filePath)
{
var file = context.Files.FirstOrDefault(f => f.Name == filePath);
if (file == null)
{
throw new ApplicationException("Could not find file: " + filePath);
}
return file;
}
}
}

39
abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/Steps/NugetReferenceReplaceStep.cs

@ -16,7 +16,8 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
new NugetReferenceReplacer(
context.Files,
"MyCompanyName",
"MyProjectName"
"MyProjectName",
context.Template.Version
).Run();
}
@ -27,12 +28,12 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
private readonly string _projectNamePlaceHolder;
private readonly string _latestNugetPackageVersion;
public NugetReferenceReplacer(List<FileEntry> entries, string companyNamePlaceHolder, string projectNamePlaceHolder)
public NugetReferenceReplacer(List<FileEntry> entries, string companyNamePlaceHolder, string projectNamePlaceHolder, string latestNugetPackageVersion)
{
_entries = entries;
_companyNamePlaceHolder = companyNamePlaceHolder;
_projectNamePlaceHolder = projectNamePlaceHolder;
_latestNugetPackageVersion = GetLatestNugetPackageVersion();
_latestNugetPackageVersion = latestNugetPackageVersion;
}
public void Run()
@ -110,38 +111,6 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
stream.Position = 0;
return stream;
}
private string GetLatestNugetPackageVersion()
{
//TODO: This should get it from the related release! Not always from the master!
var commonPropsUrl = "https://raw.githubusercontent.com/abpframework/abp/master/common.props";
var content = "";
using (var webClient = new WebClient())
{
try
{
content = webClient.DownloadString(commonPropsUrl);
}
catch (Exception)
{
throw new Exception("The Common.pros doesn't exist on github or removed to anywhere else.");
}
}
var doc = new HtmlDocument();
doc.Load(GenerateStreamFromString(content));
try
{
return doc.DocumentNode.SelectNodes("//version").FirstOrDefault().InnerHtml.Trim();
}
catch (Exception e)
{
return "";
}
}
}
}
}

2
abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/Steps/RemoveProjectFromSolutionStep.cs

@ -23,7 +23,7 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
public override void Execute(ProjectBuildContext context)
{
context.Files.RemoveAll(file => file.Name.StartsWith(_projectFolderPath));
var solutionFile = GetFile(context, _solutionFilePath);
var solutionFile = context.GetFile(_solutionFilePath);
solutionFile.NormalizeLineEndings();
solutionFile.SetLines(RemoveProject(solutionFile.GetLines().ToList()));
}

8
abp_io/src/Volo.Utils.SolutionTemplating/Volo/Utils/SolutionTemplating/Building/Steps/SwitchEntityFrameworkCoreToMongoDbStep.cs

@ -14,7 +14,7 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
private void ChangeProjectReference(ProjectBuildContext context)
{
var file = GetFile(context, "/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj");
var file = context.GetFile("/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj");
file.NormalizeLineEndings();
@ -29,12 +29,12 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
}
}
throw new ApplicationException("Could not find the 'Default' connection string in appsettings.json file!");
throw new ApplicationException("Could not find the EntityFrameworkCore reference in the MyCompanyName.MyProjectName.Web.csproj!");
}
private void ChangeWebModuleUsage(ProjectBuildContext context)
{
var file = GetFile(context, "/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs");
var file = context.GetFile("/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs");
file.NormalizeLineEndings();
@ -59,7 +59,7 @@ namespace Volo.Utils.SolutionTemplating.Building.Steps
private void ChangeConnectionString(ProjectBuildContext context)
{
var file = GetFile(context, "/src/MyCompanyName.MyProjectName.Web/appsettings.json");
var file = context.GetFile("/src/MyCompanyName.MyProjectName.Web/appsettings.json");
file.NormalizeLineEndings();

2
build-all.ps1

@ -9,6 +9,7 @@ $solutionPaths = (
"modules/users",
"modules/permission-management",
"modules/setting-management",
"modules/feature-management",
"modules/identity",
"modules/identityserver",
"modules/tenant-management",
@ -17,6 +18,7 @@ $solutionPaths = (
"modules/blogging",
"modules/audit-logging",
"modules/background-jobs",
"modules/client-simulation",
"abp_io",
"templates/module",
"templates/service",

2
common.props

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>0.14.0</Version>
<Version>0.15.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io</PackageProjectUrl>

2
docs/en/Contribution/Index.md

@ -49,4 +49,4 @@ If you decide to create some tutorials or blog posts on ABP, please inform us (b
### Bug Report
If you find any bug, please [create an issue on the Github repository](https://github.com/abpframework/abp/issues/new).
If you find any bug, please [create an issue on the Github repository](https://github.com/abpframework/abp/issues/new).

2
docs/en/Dependency-Injection.md

@ -170,7 +170,7 @@ public class BlogModule : AbpModule
There are three common ways of using a service that has already been registered.
### Contructor Injection
### Constructor Injection
This is the most common way of injecting a service into a class. For example:

10
docs/en/Getting-Started-AspNetCore-MVC-Template.md

@ -19,9 +19,9 @@ The downloaded project requires;
### The Solution Structure
Extract the zip file downloaded and open in **Visual Studio 2017 (15.7.0+)**:
Extract the zip file downloaded and open in **Visual Studio 2017 (15.9.0+)**:
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution.png)
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v2.png)
The solution has a layered structure (based on Domain Driven Design) where;
@ -30,6 +30,8 @@ The solution has a layered structure (based on Domain Driven Design) where;
* ``.Web`` is the presentation layer.
* ``.EntityFrameworkCore`` is the EF Core integration package.
EF Core database migrations are separated to a project named `.EntityFrameworkCore.DbMigrations`.
The solution also contains unit & integration test projects properly configured to work with **EF Core** & **SQLite in-memory** database.
### Creating the Database
@ -50,9 +52,9 @@ Right click to the `.Web` project and select **Set as StartUp Project**:
![set-as-startup-project](images/set-as-startup-project.png)
Open the **Package Manager Console**, select `.EntityFrameworkCore` project as the **Default Project** and run the `Update-Database` command:
Open the **Package Manager Console**, select `.EntityFrameworkCore.DbMigrations` project as the **Default Project** and run the `Update-Database` command:
![pcm-update-database](images/pcm-update-database.png)
![pcm-update-database](images/pcm-update-database-v2.png)
This will create a new database based on the configured connection string.

14
docs/en/Multi-Tenancy.md

@ -6,17 +6,17 @@ Wikipedia [defines](https://en.wikipedia.org/wiki/Multitenancy) multi-tenancy as
> Software **Multi-tenancy** refers to a software **architecture** in which a **single instance** of a software runs on a server and serves **multiple tenants**. A tenant is a group of users who share a common access with specific privileges to the software instance. With a multitenant architecture, a software application is designed to provide every tenant a **dedicated share of the instance including its data**, configuration, user management, tenant individual functionality and non-functional properties. Multi-tenancy contrasts with multi-instance architectures, where separate software instances operate on behalf of different tenants.
### Volo.Abp.MultiTenancy.Abstractions Package
### Volo.Abp.MultiTenancy Package
Volo.Abp.MultiTenancy.Abstractions package defines fundamental interfaces to make your code "multi-tenancy ready". So, install it to your project using the package manager console (PMC):
Volo.Abp.MultiTenancy package defines fundamental interfaces to make your code "multi-tenancy ready". So, install it to your project using the package manager console (PMC):
````
Install-Package Volo.Abp.MultiTenancy.Abstractions
Install-Package Volo.Abp.MultiTenancy
````
> This package is already installed by default with the startup template. So, most of the time, you don't need to install it manually.
Then you can add **AbpMultiTenancyAbstractionsModule** dependency to your module:
Then you can add **AbpMultiTenancyModule** dependency to your module:
````C#
using Volo.Abp.Modularity;
@ -24,7 +24,7 @@ using Volo.Abp.MultiTenancy;
namespace MyCompany.MyProject
{
[DependsOn(typeof(AbpMultiTenancyAbstractionsModule))]
[DependsOn(typeof(AbpMultiTenancyModule))]
public class MyModule : AbpModule
{
//...
@ -98,7 +98,7 @@ Volo.Abp.MultiTenancy is the actual package that makes your application multi-te
Install-Package Volo.Abp.MultiTenancy
````
Then you can add **AbpMultiTenancyAbstractionsModule** dependency to your module:
Then you can add **AbpMultiTenancyModule** dependency to your module:
````C#
using Volo.Abp.Modularity;
@ -114,7 +114,7 @@ namespace MyCompany.MyProject
}
````
> If you add AbpMultiTenancyModule dependency to your module, then you don't need to add AbpMultiTenancyAbstractionsModule dependency separately since AbpMultiTenancyModule already depends on it.
> If you add AbpMultiTenancyModule dependency to your module, then you don't need to add AbpMultiTenancyModule dependency separately since AbpMultiTenancyModule already depends on it.
#### Determining Current Tenant

6
docs/en/Tutorials/AspNetCore-Mvc/Part-I.md

@ -20,7 +20,7 @@ Go to the [startup template page](https://abp.io/Templates) and download a new p
This is the how the layered solution structure looks after it's created from the startup template:
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution.png)
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v2.png)
### Create the Book Entity
@ -91,9 +91,9 @@ EF Core requires you to relate entities with your DbContext. The easiest way to
#### Add New Migration & Update the Database
The Startup template uses [EF Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/) to create and maintain the database schema. Open the **Package Manager Console (PMC)** (under the *Tools/Nuget Package Manager* menu), select the `Acme.BookStore.EntityFrameworkCore` as the **default project** and execute the following command:
The Startup template uses [EF Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/) to create and maintain the database schema. Open the **Package Manager Console (PMC)** (under the *Tools/Nuget Package Manager* menu), select the `Acme.BookStore.EntityFrameworkCore.DbMigrations` as the **default project** and execute the following command:
![bookstore-pmc-add-book-migration](images/bookstore-pmc-add-book-migration.png)
![bookstore-pmc-add-book-migration](images/bookstore-pmc-add-book-migration-v2.png)
This will create a new migration class inside the `Migrations` folder. Then execute the `Update-Database` command to update the database schema:

2
docs/en/Tutorials/AspNetCore-Mvc/Part-III.md

@ -14,8 +14,6 @@ You can download the **source code** of the application [from here](https://gith
There are two test projects in the solution:
![bookstore-test-projects](images/bookstore-test-projects.png)
* `Acme.BookStore.Application.Tests` is for unit & integration tests. You can write tests for application service methods. It uses **EF Core SQLite in-memory** database.
* `Acme.BookStore.Web.Tests` is for full stack integration tests including the web layer. So, you can write tests for UI pages too.

BIN
docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
docs/en/images/bookstore-visual-studio-solution-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
docs/en/images/pcm-update-database-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

54
docs/zh-Hans/Blog-Posts/2019-02-22/Post.md

@ -0,0 +1,54 @@
# 微服务演示,项目状态和路线图
在ABP vNext上的[第一个公告](https://cn.abp.io/blog/abp/Abp-vNext-Announcement)之后,我们对代码库进行了很多改进([GitHub存储库](https://github.com/abpframework/abp)上的1100多次提交).我们已经创建了功能,示例,文档等等.在这篇文章中,我想告诉你一些新闻和项目的状态.
## 微服务演示解决方案
ABP框架的主要目标之一是提供[创建微服务解决方案的便利基础设施](https://cn.abp.io/documents/abp/latest/Microservice-Architecture).
我们一直在努力开发微服务解决方案演示.初始版本已完成并[文档化](https://cn.abp.io/documents/abp/latest/Samples/Microservice-Demo).该示例解决方案旨在演示一个简单而完整的微服务解决方案;
- 具有多个独立的,可自我部署的**微服务**.
- 多个**Web应用程序**,每个都使用不同的API网关.
- 使用[Ocelot](https://github.com/ThreeMammals/Ocelot)库开发了多个**网关** / BFF(后端为前端(Backend for Frontends)).
- 使用[IdentityServer](https://identityserver.io/)框架开发**身份验证服务**.它也是一个带有必要UI的SSO(单点登录)应用程序.
- 有**多个数据库**.一些微服务有自己的数据库,而一些服务/应用程序共享一个数据库(以演示不同的用例).
- 具有不同类型的数据库:**SQL Server**(使用**Entity Framework Core** ORM)和**MongoDB**.
- 有一个**控制台应用程序**来显示通过身份验证使用服务的最简单方法.
- 使用[Redis](https://redis.io/)进行**分布式缓存**.
- 使用[RabbitMQ](https://www.rabbitmq.com/)进行服务到服务(service-to-service)的**消息传递**.
- 使用[Docker](https://www.docker.com/)和[Kubernates](https://kubernetes.io/)**部署**并运行所有服务和应用程序.
- 使用[Elasticsearch](https://www.elastic.co/products/elasticsearch)和[Kibana](https://www.elastic.co/products/kibana)存储和可视化日志(使用[Serilog](https://serilog.net/)编写).
有关解决方案的详细说明,请参阅[其文档](https://cn.abp.io/documents/abp/latest/Samples/Microservice-Demo).
## 改进/功能
我们已经开发了许多功能,包括**分布式事件总线**(与RabbitMQ集成),**IdentityServer4集成**以及几乎所有功能的增强.我们不断重构和添加测试,以使框架更稳定和生产就绪.它正在[快速增长](https://github.com/abpframework/abp/graphs/contributors).
## 路线图
在第一个稳定版本(v1.0)之前还有很多工作要做.您可以在GitHub仓库上看到[优先的积压项目](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3ABacklog).
根据我们的估计,我们计划在2019年第二季度(可能在五月或六月)发布v1.0.所以,不用等待太长时间了.我们也对第一个稳定版本感到非常兴奋.
我们还将完善[文档](https://cn.abp.io/documents/abp/latest),因为它现在还远未完成.
第一个版本可能不包含SPA模板.但是,如果可能的话,我们想要准备一个简单些的.SPA框架还没有确定下来.备选有:**Angular,React和Blazor**.请将您的想法写为对此帖的评论.
## 中文网
中国有一个大型的ABP社区.他们创建了一个中文版的abp.io网站:https://cn.abp.io/. 他们一直在保持更新.感谢中国的开发人员,特别是[Liming Ma](https://github.com/maliming).
## NDC {London} 2019
很高兴作为合作伙伴参加[NDC {London}](https://ndc-london.com/)2019 .我们已经与许多开发人员讨论过当前的ASP.NET Boilerplate和ABP vNext,我们得到了很好的反馈.
我们还有机会与[Scott Hanselman](https://twitter.com/shanselman)和[Jon Galloway](https://twitter.com/jongalloway)交谈.他们参观了我们的展位,我们谈到了ABP vNext的想法.他们喜欢新的ABP框架的功能,方法和目标.在twitter上查看一些照片和评论:
![scott-and-jon](scott-and-jon.png)
## 跟上步伐
* 您可以标星并关注**GitHub**存储库:https://github.com/abpframework/abp
* 您可以关注官方**Twitter**帐户获取新闻:https://twitter.com/abpframework

BIN
docs/zh-Hans/Blog-Posts/2019-02-22/scott-and-jon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 KiB

20
docs/zh-Hans/Getting-Started-AspNetCore-Application.md

@ -156,6 +156,26 @@ services.AddApplication<AppModule>(options =>
});
````
4. 更新 `Program.cs`代码, 不再使用`WebHost.CreateDefaultBuilder()`方法(因为它使用默认的DI容器):
````csharp
public class Program
{
public static void Main(string[] args)
{
BuildWebHostInternal(args).Run();
}
public static IWebHost BuildWebHostInternal(string[] args) =>
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
}
````
### 源码
从[此处](../samples/BasicAspNetCoreApplication)获取本教程中创建的示例项目的源代码.

10
docs/zh-Hans/Getting-Started-AspNetCore-MVC-Template.md

@ -12,14 +12,14 @@
下载的项目需要:
* [Visual Studio 2017 (v15.7.0+)](https://visualstudio.microsoft.com/tr/downloads/)
* [Visual Studio 2017 (v15.9.0+)](https://visualstudio.microsoft.com/tr/downloads/)
* [.NET Core 2.1.1+](https://www.microsoft.com/net/download/dotnet-core/)
### 解决方案结构
下载后解压文件并在 **Visual Studio 2017(15.7.0 +)** 中打开:
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution.png)
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v2.png)
该解决方案具有分层结构(基于域驱动设计), 其中:
@ -28,6 +28,8 @@
* ``.Web`` 为是表示层.
* ``.EntityFrameworkCore`` 是EF Core集成.
EF Core 数据库迁移被分离到名为`.EntityFrameworkCore.DbMigrations`项目中.
解决方案还包含配置好的的单元&集成测试项目, 以便与 **EF Core****SQLite内存中** 数据库配合使用.
### 创建数据库
@ -48,9 +50,9 @@
![set-as-startup-project](images/set-as-startup-project.png)
打开**包管理器控制台(Package Manager Console)**, 选择`.EntityFrameworkCore`项目作为**默认项目**并运行`Update-Database`命令:
打开**包管理器控制台(Package Manager Console)**, 选择`.EntityFrameworkCore.DbMigrations`项目作为**默认项目**并运行`Update-Database`命令:
![pcm-update-database](images/pcm-update-database.png)
![pcm-update-database](images/pcm-update-database-v2.png)
这将基于配置的连接字符串创建新数据库.

14
docs/zh-Hans/Multi-Tenancy.md

@ -6,17 +6,17 @@ ABP的多租户模块提供了创建多租户应用程序的基本功能.
> 软件多租户技术指的是一种软件架构,这种架构可以使用软件的单实例运行并为多个租户提供服务.租户是通过软件实例的特定权限共享通用访问的一组用户.使用多租户架构,软件应用为每个租户提供实例的专用共享,包括实例的数据、配置、用户管理、租户的私有功能和非功能属性.多租户与多实例架构形成对比,将软件实例的行为根据不同的租户分割开来.
### Volo.Abp.MultiTenancy.Abstractions
### Volo.Abp.MultiTenancy
Volo.Abp.MultiTenancy.Abstractions定义了一些基础接口让你的代码"multi-tenancy ready",使用包管理器控制台(PMC)将它安装到你的项目中:
Volo.Abp.MultiTenancy"multi-tenancy ready",使用包管理器控制台(PMC)将它安装到你的项目中:
````
Install-Package Volo.Abp.MultiTenancy.Abstractions
Install-Package Volo.Abp.MultiTenancy
````
> 这个包默认安装在了快速启动模板中.所以,大多数情况下,你不需要手动安装它.
然后你可以添加 **AbpMultiTenancyAbstractionsModule** 依赖到你的模块:
然后你可以添加 **AbpMultiTenancyModule** 依赖到你的模块:
````C#
using Volo.Abp.Modularity;
@ -24,7 +24,7 @@ using Volo.Abp.MultiTenancy;
namespace MyCompany.MyProject
{
[DependsOn(typeof(AbpMultiTenancyAbstractionsModule))]
[DependsOn(typeof(AbpMultiTenancyModule))]
public class MyModule : AbpModule
{
//...
@ -98,7 +98,7 @@ Volo.Abp.MultiTenancy 才是让你的程序实现多租户的真正的包.使用
Install-Package Volo.Abp.MultiTenancy
````
然后添加 **AbpMultiTenancyAbstractionsModule** 依赖到你的模块中:
然后添加 **AbpMultiTenancyModule** 依赖到你的模块中:
````C#
using Volo.Abp.Modularity;
@ -114,7 +114,7 @@ namespace MyCompany.MyProject
}
````
> 如果你添加了AbpMultiTenancyModule依赖,就不需要再另外添加AbpMultiTenancyAbstractionsModule依赖了,因为AbpMultiTenancyModule已经依赖它了.
> 如果你添加了AbpMultiTenancyModule依赖,就不需要再另外添加AbpMultiTenancyModule依赖了,因为AbpMultiTenancyModule已经依赖它了.
#### 确定当前租户

1433
docs/zh-Hans/Samples/Microservice-Demo.md

File diff suppressed because it is too large

6
docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-I.md

@ -20,7 +20,7 @@
下面的图片展示了从启动模板创建的项目是如何分层的.
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution.png)
![bookstore-visual-studio-solution](images/bookstore-visual-studio-solution-v2.png)
### 创建Book实体
@ -91,9 +91,9 @@ public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
#### 添加新的Migration并更新数据库
这个启动模板使用了[EF Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/)来创建并维护数据库结构.打开 **Package Manager Console (PMC)** (工具/Nuget包管理器菜单),选择 `Acme.BookStore.EntityFrameworkCore`作为默认的项目然后执行下面的命令:
这个启动模板使用了[EF Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/)来创建并维护数据库结构.打开 **Package Manager Console (PMC)** (工具/Nuget包管理器菜单),选择 `Acme.BookStore.EntityFrameworkCore.DbMigrations`作为默认的项目然后执行下面的命令:
![bookstore-pmc-add-book-migration](images/bookstore-pmc-add-book-migration.png)
![bookstore-pmc-add-book-migration](images/bookstore-pmc-add-book-migration-v2.png)
这样就会在`Migrations`文件夹中创建一个新的migration类.然后执行`Update-Database`命令更新数据库结构.

1
docs/zh-Hans/Tutorials/AspNetCore-Mvc/Part-III.md

@ -14,7 +14,6 @@
本解决方案中有两个测试项目:
![bookstore-test-projects](images/bookstore-test-projects.png)
* `Acme.BookStore.Application.Tests` 项目用于单元测试和集成测试.你可以在这个项目中为Application Service方法写测试代码.这个项目使用了 **EF Core SQLite in-memory** 数据库.
* `Acme.BookStore.Web.Tests` 项目用于包含Web层的完整集成测试.所以,你也可以在这里写关于UI页面的测试.

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
docs/zh-Hans/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
docs/zh-Hans/images/bookstore-visual-studio-solution-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
docs/zh-Hans/images/microservice-sample-authserver-home.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/zh-Hans/images/microservice-sample-authserver-login.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/zh-Hans/images/microservice-sample-backend-ui-permissions.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
docs/zh-Hans/images/microservice-sample-backend-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/zh-Hans/images/microservice-sample-blogservice-permission-in-database.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
docs/zh-Hans/images/microservice-sample-diagram-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
docs/zh-Hans/images/microservice-sample-kibana-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
docs/zh-Hans/images/microservice-sample-kibana-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/zh-Hans/images/microservice-sample-product-module-in-solution.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/zh-Hans/images/microservice-sample-public-product-list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/zh-Hans/images/microservice-sample-solution.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/zh-Hans/images/pcm-update-database-v2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

21
framework/Volo.Abp.sln

@ -5,23 +5,8 @@ VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CBCC288A-53C3-402F-99F7-E468738560F5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{447C8A77-E5F0-4538-8687-7383196D04EA}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker-files", "docker-files", "{0BEA55D6-E0B8-40DD-A256-B34C4DD990A5}"
ProjectSection(SolutionItems) = preProject
..\docker\docker-compose.yml = ..\docker\docker-compose.yml
..\docker\down.ps1 = ..\docker\down.ps1
..\docker\haproxy.cfg = ..\docker\haproxy.cfg
..\docker\up.ps1 = ..\docker\up.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{6D893E48-0739-401A-9AD1-286BCB6E5517}"
ProjectSection(SolutionItems) = preProject
..\build\build.ps1 = ..\build\build.ps1
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AbpTestBase", "test\AbpTestBase\AbpTestBase.csproj", "{1020F5FD-6A97-40C2-AFCA-EBDF641DF111}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore", "src\Volo.Abp.AspNetCore\Volo.Abp.AspNetCore.csproj", "{02BE03BA-3411-448C-AB61-CB36407CC49A}"
@ -102,7 +87,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Data", "src\Volo.A
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Data.Tests", "test\Volo.Abp.Data.Tests\Volo.Abp.Data.Tests.csproj", "{5D2275B7-0745-420A-AF1C-32C563DAB5C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MultiTenancy.Abstractions", "src\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj", "{10EB789E-C993-4BE8-BA43-C419936C7233}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MultiTenancy", "src\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj", "{10EB789E-C993-4BE8-BA43-C419936C7233}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.ObjectMapping", "src\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj", "{8D22063D-88DE-4F7A-A917-C81AB4ACE601}"
EndProject
@ -228,7 +213,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.Con
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Features", "src\Volo.Abp.Features\Volo.Abp.Features.csproj", "{01E3D389-8872-4EB1-9D3D-13B6ED54DE0E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Features.Tests", "test\Volo.Abp.Features.Tests\Volo.Abp.Features.Tests.csproj", "{575BEFA1-19C2-49B1-8D31-B5D4472328DE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Features.Tests", "test\Volo.Abp.Features.Tests\Volo.Abp.Features.Tests.csproj", "{575BEFA1-19C2-49B1-8D31-B5D4472328DE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -657,8 +642,6 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0BEA55D6-E0B8-40DD-A256-B34C4DD990A5} = {CBCC288A-53C3-402F-99F7-E468738560F5}
{6D893E48-0739-401A-9AD1-286BCB6E5517} = {CBCC288A-53C3-402F-99F7-E468738560F5}
{1020F5FD-6A97-40C2-AFCA-EBDF641DF111} = {447C8A77-E5F0-4538-8687-7383196D04EA}
{02BE03BA-3411-448C-AB61-CB36407CC49A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{B1D860BB-6EC6-4BAE-ADAA-C2AEC2FFB510} = {447C8A77-E5F0-4538-8687-7383196D04EA}

2
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo.Abp.AspNetCore.MultiTenancy.csproj

@ -15,7 +15,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore\Volo.Abp.AspNetCore.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
</ItemGroup>
</Project>

2
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/AbpAspNetCoreMultiTenancyModule.cs

@ -5,7 +5,7 @@ using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
{
[DependsOn(
typeof(AbpMultiTenancyAbstractionsModule),
typeof(AbpMultiTenancyModule),
typeof(AbpAspNetCoreModule)
)]
public class AbpAspNetCoreMultiTenancyModule : AbpModule

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs

@ -5,6 +5,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class CookieTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Cookie";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
return httpContext.Request?.Cookies[context.GetAspNetCoreMultiTenancyOptions().TenantKey];

16
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs

@ -9,23 +9,33 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public class DomainTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Domain";
public override string Name => ContributorName;
private static readonly string[] ProtocolPrefixes = { "http://", "https://" };
private readonly string _domainFormat;
public DomainTenantResolveContributor(string domainFormat)
{
_domainFormat = domainFormat.RemovePreFix("http://", "https://");
_domainFormat = domainFormat.RemovePreFix(ProtocolPrefixes);
}
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
protected override string GetTenantIdOrNameFromHttpContextOrNull(
ITenantResolveContext context,
HttpContext httpContext)
{
if (httpContext.Request?.Host == null)
{
return null;
}
var hostName = httpContext.Request.Host.Host.RemovePreFix("http://", "https://");
var hostName = httpContext.Request.Host.Host.RemovePreFix(ProtocolPrefixes);
var extractResult = FormattedStringValueExtracter.Extract(hostName, _domainFormat, ignoreCase: true);
context.Handled = true;
if (!extractResult.IsMatch)
{
return null;

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs

@ -9,6 +9,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class HeaderTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Header";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request == null || httpContext.Request.Headers.IsNullOrEmpty())

39
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpContextTenantResolveResultAccessor.cs

@ -0,0 +1,39 @@
using Microsoft.AspNetCore.Http;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
{
[Dependency(ReplaceServices = true)]
public class HttpContextTenantResolveResultAccessor : ITenantResolveResultAccessor, ITransientDependency
{
public TenantResolveResult Result
{
get
{
if (_httpContextAccessor.HttpContext == null)
{
return null;
}
return _httpContextAccessor.HttpContext.Items[""] as TenantResolveResult;
}
set
{
if (_httpContextAccessor.HttpContext == null)
{
return;
}
_httpContextAccessor.HttpContext.Items[""] = value;
}
}
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextTenantResolveResultAccessor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
}
}

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs

@ -7,9 +7,9 @@ using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
{
public abstract class HttpTenantResolveContributorBase : ITenantResolveContributor
public abstract class HttpTenantResolveContributorBase : TenantResolveContributorBase
{
public virtual void Resolve(ITenantResolveContext context)
public override void Resolve(ITenantResolveContext context)
{
var httpContext = context.GetHttpContext();
if (httpContext == null)

51
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs

@ -1,6 +1,5 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
using Volo.Abp.MultiTenancy;
@ -12,46 +11,48 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
private readonly ITenantResolver _tenantResolver;
private readonly ITenantStore _tenantStore;
private readonly ICurrentTenantIdAccessor _currentTenantIdAccessor;
private readonly ICurrentTenant _currentTenant;
private readonly ITenantResolveResultAccessor _tenantResolveResultAccessor;
public MultiTenancyMiddleware(
RequestDelegate next,
ITenantResolver tenantResolver,
ITenantStore tenantStore,
ICurrentTenantIdAccessor currentTenantIdAccessor)
ICurrentTenant currentTenant,
ITenantResolveResultAccessor tenantResolveResultAccessor)
{
_next = next;
_tenantResolver = tenantResolver;
_tenantStore = tenantStore;
_currentTenantIdAccessor = currentTenantIdAccessor;
_currentTenant = currentTenant;
_tenantResolveResultAccessor = tenantResolveResultAccessor;
}
public async Task Invoke(HttpContext httpContext)
{
using (SetCurrentTenant(await ResolveCurrentTenantAsync()))
{
await _next(httpContext);
}
}
var resolveResult = _tenantResolver.ResolveTenantIdOrName();
_tenantResolveResultAccessor.Result = resolveResult;
private async Task<TenantInfo> ResolveCurrentTenantAsync()
{
var tenantIdOrName = _tenantResolver.ResolveTenantIdOrName();
if (tenantIdOrName == null)
TenantConfiguration tenant = null;
if (resolveResult.TenantIdOrName != null)
{
return null;
tenant = await FindTenantAsync(resolveResult.TenantIdOrName);
if (tenant == null)
{
//TODO: A better exception?
throw new AbpException(
"There is no tenant with given tenant id or name: " + resolveResult.TenantIdOrName
);
}
}
var tenant = await FindTenantAsync(tenantIdOrName);
if (tenant == null)
using (_currentTenant.Change(tenant?.Id, tenant?.Name))
{
throw new AbpException("There is no tenant with given tenant id or name: " + tenantIdOrName);
await _next(httpContext);
}
return tenant;
}
private async Task<TenantInfo> FindTenantAsync(string tenantIdOrName)
private async Task<TenantConfiguration> FindTenantAsync(string tenantIdOrName)
{
if (Guid.TryParse(tenantIdOrName, out var parsedTenantId))
{
@ -62,15 +63,5 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
return await _tenantStore.FindAsync(tenantIdOrName);
}
}
private IDisposable SetCurrentTenant([CanBeNull] TenantInfo tenant)
{
var parentScope = _currentTenantIdAccessor.Current;
_currentTenantIdAccessor.Current = new TenantIdWrapper(tenant?.Id);
return new DisposeAction(() =>
{
_currentTenantIdAccessor.Current = parentScope;
});
}
}
}

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs

@ -5,6 +5,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class QueryStringTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "QueryString";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request == null || !httpContext.Request.QueryString.HasValue)

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs

@ -7,6 +7,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class RouteTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Route";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
var tenantId = httpContext.GetRouteValue(context.GetAspNetCoreMultiTenancyOptions().TenantKey);

4
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteFeatureChecker.cs

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Features;

23
framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/RemoteLanguageProvider.cs

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.Client
{
public class RemoteLanguageProvider : ILanguageProvider, ITransientDependency
{
protected ICachedApplicationConfigurationClient ConfigurationClient { get; }
public RemoteLanguageProvider(ICachedApplicationConfigurationClient configurationClient)
{
ConfigurationClient = configurationClient;
}
public async Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync()
{
var configuration = await ConfigurationClient.GetAsync();
return configuration.Localization.Languages;
}
}
}

9
framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationFeatureConfigurationDto.cs

@ -1,9 +1,16 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
[Serializable]
public class ApplicationFeatureConfigurationDto
{
public Dictionary<string, string> Values { get; set; }
public ApplicationFeatureConfigurationDto()
{
Values = new Dictionary<string, string>();
}
}
}

5
framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs

@ -1,16 +1,21 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
[Serializable]
public class ApplicationLocalizationConfigurationDto
{
//TODO: Rename to Texts?
public Dictionary<string, Dictionary<string, string>> Values { get; set; }
public List<LanguageInfo> Languages { get; set; }
public ApplicationLocalizationConfigurationDto()
{
Values = new Dictionary<string, Dictionary<string, string>>();
Languages = new List<LanguageInfo>();
}
}
}

3
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/AbpAspNetCoreMvcUiBootstrapModule.cs

@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/tenant-switch.js

@ -3,7 +3,7 @@
var tenantSwitchModal = new abp.ModalManager(abp.appPath + 'Abp/MultiTenancy/TenantSwitchModal');
$(function() {
$('#TenantSwitchToolbarLink').click(function(e) {
$('#AbpTenantSwitchLink').click(function(e) {
e.preventDefault();
tenantSwitchModal.open();
});

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj

@ -18,11 +18,9 @@
<ItemGroup>
<EmbeddedResource Include="Pages\**\*.cshtml" />
<EmbeddedResource Include="Pages\**\*.js" />
<EmbeddedResource Include="Volo\Abp\AspNetCore\Mvc\UI\MultiTenancy\Components\**\*.cshtml" />
<EmbeddedResource Include="Volo\Abp\AspNetCore\Mvc\UI\MultiTenancy\Localization\*.json" />
<Content Remove="Pages\**\*.cshtml" />
<Content Remove="Pages\**\*.js" />
<Content Remove="Volo\Abp\AspNetCore\Mvc\UI\MultiTenancy\Components\**\*.cshtml" />
<Content Remove="Volo\Abp\AspNetCore\Mvc\UI\MultiTenancy\Localization\*.json" />
</ItemGroup>

9
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/AbpAspNetCoreMvcUiMultiTenancyModule.cs

@ -1,11 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@ -36,11 +34,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy
options.FileSets.AddEmbedded<AbpAspNetCoreMvcUiMultiTenancyModule>();
});
Configure<ToolbarOptions>(options =>
{
options.Contributors.Add(new MultiTenancyToolbarContributor());
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources

17
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml

@ -1,17 +0,0 @@
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch
@model TenantSwitchViewComponent.TenantSwitchViewModel
@if (!Model.CurrentUser.IsAuthenticated)
{
<li class="nav-item">
<a abp-button="Link" id="TenantSwitchToolbarLink" href="#">
@if (Model.Tenant == null)
{
<text>@@host</text>
}
else
{
<text>@@@Model.Tenant.Name</text>
}
</a>
</li>
}

51
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/TenantSwitchViewComponent.cs

@ -1,51 +0,0 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch
{
public class TenantSwitchViewComponent : AbpViewComponent
{
/// <summary>
/// -1,000,000
/// </summary>
public const int Order = -1_000_000;
protected ITenantStore TenantStore { get; }
protected ICurrentTenant CurrentTenant { get; }
protected ICurrentUser CurrentUser { get; }
public TenantSwitchViewComponent(
ITenantStore tenantStore,
ICurrentTenant currentTenant,
ICurrentUser currentUser)
{
TenantStore = tenantStore;
CurrentTenant = currentTenant;
CurrentUser = currentUser;
}
public async Task<IViewComponentResult> InvokeAsync()
{
var model = new TenantSwitchViewModel
{
CurrentUser = CurrentUser
};
if (CurrentTenant.Id.HasValue)
{
model.Tenant = await TenantStore.FindAsync(CurrentTenant.GetId());
}
return View("~/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Components/TenantSwitch/Default.cshtml", model);
}
public class TenantSwitchViewModel
{
public TenantInfo Tenant { get; set; }
public ICurrentUser CurrentUser { get; set; }
}
}
}

8
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json

@ -1,9 +1,11 @@
{
{
"culture": "en",
"texts": {
"GivenTenantIsNotAvailable": "Given tenant is not available: {0}",
"SwitchTenant": "Switch tenant",
"Tenant": "Tenant",
"Switch": "switch",
"Name": "Name",
"SwitchTenantHint": "Leave the name field blank to switch to the host side."
"SwitchTenantHint": "Leave the name field blank to switch to the host side.",
"NotSelected": "Not selected"
}
}

6
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json

@ -2,8 +2,10 @@
"culture": "tr",
"texts": {
"GivenTenantIsNotAvailable": "İstenilen müşteri bulunamadı: {0}",
"SwitchTenant": "Müşteri değiştir",
"Tenant": "Müşteri",
"Switch": "değiştir",
"Name": "İsim",
"SwitchTenantHint": "Host tarafına geçmek için isim alanını boş bırakın."
"SwitchTenantHint": "Host tarafına geçmek için isim alanını boş bırakın.",
"NotSelected": "Seçili değil"
}
}

21
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/MultiTenancyToolbarContributor.cs

@ -1,21 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Components.TenantSwitch;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars;
namespace Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy
{
public class MultiTenancyToolbarContributor : IToolbarContributor
{
public Task ConfigureToolbarAsync(IToolbarConfigurationContext context)
{
if (context.Toolbar.Name != StandardToolbars.Main)
{
return Task.CompletedTask;
}
context.Toolbar.Items.Add(new ToolbarItem(typeof(TenantSwitchViewComponent), TenantSwitchViewComponent.Order));
return Task.CompletedTask;
}
}
}

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/AbpAspNetCoreMvcUIBasicThemeModule.cs

@ -1,4 +1,5 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Toolbars;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared;
@ -11,7 +12,8 @@ using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic
{
[DependsOn(
typeof(AbpAspNetCoreMvcUiThemeSharedModule)
typeof(AbpAspNetCoreMvcUiThemeSharedModule),
typeof(AbpAspNetCoreMvcUiMultiTenancyModule)
)]
public class AbpAspNetCoreMvcUiBasicThemeModule : AbpModule
{

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Menu/Default.cshtml

@ -7,7 +7,7 @@
var disabled = menuItem.IsDisabled ? "disabled" : string.Empty;
if (menuItem.IsLeaf)
{
@if (menuItem.Url != null)
if (menuItem.Url != null)
{
<li class="nav-item @cssClass @disabled" @elementId>
<a class="nav-link" href="@(menuItem.Url ?? "#")">

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Menu/_MenuItem.cshtml

@ -7,7 +7,7 @@
}
@if (Model.IsLeaf)
{
@if (Model.Url != null)
if (Model.Url != null)
{
<a class="dropdown-item @cssClass @disabled" href="@(Model.Url ?? "#")" @Html.Raw(elementId)>
@Model.DisplayName

34
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml

@ -1,10 +1,20 @@
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Microsoft.Extensions.Localization
@using Microsoft.Extensions.Options
@using Volo.Abp.AspNetCore.MultiTenancy
@using Volo.Abp.AspNetCore.Mvc.AntiForgery
@using Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Bundling
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.MainNavbar
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.PageAlerts
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Components
@using Volo.Abp.MultiTenancy
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@inject IBrandingProvider BrandingProvider
@inject IOptions<MultiTenancyOptions> MultiTenancyOptions
@inject ICurrentTenant CurrentTenant
@inject IStringLocalizer<AbpUiMultiTenancyResource> MultiTenancyStringLocalizer
@inject ITenantResolveResultAccessor TenantResolveResultAccessor
@{
Layout = null;
AbpAntiForgeryManager.SetCookie();
@ -23,7 +33,7 @@
<abp-style-bundle name="@BasicThemeBundles.Styles.Global" />
@RenderSection("styles", false)
@await RenderSectionAsync("styles", false)
</head>
<body class="abp-account-layout">
@ -32,6 +42,24 @@
<div class="@containerClass">
<abp-row>
<abp-column size-md="_4" offset-md="_4">
@if (MultiTenancyOptions.Value.IsEnabled &&
(TenantResolveResultAccessor.Result?.AppliedResolvers?.Contains(CookieTenantResolveContributor.ContributorName) == true))
{
<div class="tenant-switch-box" style="background-color: #eee; margin-bottom: 20px; color: #000; padding: 10px; text-align: center;">
<span style="color: #666;">@MultiTenancyStringLocalizer["Tenant"]: </span>
<strong>
@if (CurrentTenant.Id == null)
{
<i>@MultiTenancyStringLocalizer["NotSelected"]</i>
}
else
{
@(CurrentTenant.Name ?? CurrentTenant.Id.Value.ToString())
}
</strong>
(<a id="AbpTenantSwitchLink" style="color: #333; cursor: pointer">@MultiTenancyStringLocalizer["Switch"]</a>)
</div>
}
@(await Component.InvokeAsync<PageAlertsViewComponent>())
@RenderBody()
</abp-column>
@ -43,7 +71,7 @@
<script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"></script>
<script type="text/javascript" src="~/Abp/ServiceProxyScript"></script>
@RenderSection("scripts", false)
@await RenderSectionAsync("scripts", false)
</body>
</html>

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml

@ -23,7 +23,7 @@
<abp-style-bundle name="@BasicThemeBundles.Styles.Global" />
@RenderSection("styles", false)
@await RenderSectionAsync("styles", false)
</head>
<body class="abp-application-layout">
@ -39,7 +39,7 @@
<script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"></script>
<script type="text/javascript" src="~/Abp/ServiceProxyScript"></script>
@RenderSection("scripts", false)
@await RenderSectionAsync("scripts", false)
</body>
</html>

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml

@ -22,7 +22,7 @@
<abp-style-bundle name="@BasicThemeBundles.Styles.Global" />
@RenderSection("styles", false)
@await RenderSectionAsync("styles", false)
</head>
<body class="abp-empty-layout">
@ -36,7 +36,7 @@
<script type="text/javascript" src="~/Abp/ApplicationConfigurationScript"></script>
<script type="text/javascript" src="~/Abp/ServiceProxyScript"></script>
@RenderSection("scripts", false)
@await RenderSectionAsync("scripts", false)
</body>
</html>

1
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.csproj

@ -31,6 +31,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy\Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared\Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.csproj" />
</ItemGroup>

3
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/AbpAspNetCoreMvcUiThemeSharedModule.cs

@ -1,5 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling;

17
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js

@ -338,6 +338,23 @@
}
}
configuration.language = {
info: localize("PagerInfo"),
infoFiltered: localize("PagerInfoFiltered"),
infoEmpty: localize("PagerInfoEmpty"),
search: localize("PagerSearch"),
processing: localize("ProcessingWithThreeDot"),
loadingRecords: localize("LoadingWithThreeDot"),
lengthMenu: localize("PagerShowMenuEntries"),
emptyTable: localize("NoDataAvailableInDatatable"),
paginate: {
first: localize("PagerFirst"),
last: localize("PagerLast"),
previous: localize("PagerPrevious"),
next: localize("PagerNext")
}
};
configuration.dom = '<"dataTable_filters"f>rt<"row dataTable_footer"<"col-auto"l><"col-auto"i><"col"p>>';
return configuration;

0
framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/ILayoutManager.cs → framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/IPageLayout.cs

15
framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Http/AbpFormFileExtensions.cs

@ -0,0 +1,15 @@
using System.IO;
namespace Microsoft.AspNetCore.Http
{
public static class AbpFormFileExtensions
{
public static byte[] GetAllBytes(this IFormFile file)
{
using (var stream = file.OpenReadStream())
{
return stream.GetAllBytes();
}
}
}
}

3
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AbpController.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
@ -29,6 +30,8 @@ namespace Volo.Abp.AspNetCore.Mvc
public ICurrentTenant CurrentTenant { get; set; }
public IAuthorizationService AuthorizationService { get; set; }
protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current;
public IClock Clock { get; set; }

19
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs

@ -24,6 +24,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
private readonly ISettingProvider _settingProvider;
private readonly ISettingDefinitionManager _settingDefinitionManager;
private readonly IFeatureDefinitionManager _featureDefinitionManager;
private readonly ILanguageProvider _languageProvider;
public AbpApplicationConfigurationAppService(
IOptions<AbpLocalizationOptions> localizationOptions,
@ -33,7 +34,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
ICurrentUser currentUser,
ISettingProvider settingProvider,
SettingDefinitionManager settingDefinitionManager,
IFeatureDefinitionManager featureDefinitionManager)
IFeatureDefinitionManager featureDefinitionManager,
ILanguageProvider languageProvider)
{
_serviceProvider = serviceProvider;
_abpAuthorizationPolicyProvider = abpAuthorizationPolicyProvider;
@ -42,6 +44,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
_settingProvider = settingProvider;
_settingDefinitionManager = settingDefinitionManager;
_featureDefinitionManager = featureDefinitionManager;
_languageProvider = languageProvider;
_localizationOptions = localizationOptions.Value;
}
@ -53,7 +56,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
{
Auth = await GetAuthConfigAsync(),
Features = await GetFeaturesConfigAsync(),
Localization = GetLocalizationConfig(),
Localization = await GetLocalizationConfigAsync(),
CurrentUser = GetCurrentUser(),
Setting = await GetSettingConfigAsync()
};
@ -87,10 +90,12 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
return authConfig;
}
protected virtual ApplicationLocalizationConfigurationDto GetLocalizationConfig()
protected virtual async Task<ApplicationLocalizationConfigurationDto> GetLocalizationConfigAsync()
{
var localizationConfig = new ApplicationLocalizationConfigurationDto();
localizationConfig.Languages.AddRange(await _languageProvider.GetLanguagesAsync());
foreach (var resource in _localizationOptions.Resources.Values)
{
var dictionary = new Dictionary<string, string>();
@ -104,8 +109,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
dictionary[localizedString.Name] = localizedString.Value;
}
var resourceName = LocalizationResourceNameAttribute.GetName(resource.ResourceType);
localizationConfig.Values[resourceName] = dictionary;
localizationConfig.Values[resource.ResourceName] = dictionary;
}
return localizationConfig;
@ -133,10 +137,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
protected virtual async Task<ApplicationFeatureConfigurationDto> GetFeaturesConfigAsync()
{
var result = new ApplicationFeatureConfigurationDto
{
Values = new Dictionary<string, string>()
};
var result = new ApplicationFeatureConfigurationDto();
foreach (var featureDefinition in _featureDefinitionManager.GetAll())
{

1
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Auditing/AbpAuditActionFilter.cs

@ -92,6 +92,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Auditing
auditLog = auditLogScope.Log;
auditLogAction = _auditingHelper.CreateAuditLogAction(
auditLog,
context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.AsType(),
context.ActionDescriptor.AsControllerActionDescriptor().MethodInfo,
context.ActionArguments

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

@ -16,7 +16,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Data\Volo.Abp.Data.csproj" />
<ProjectReference Include="..\Volo.Abp.Json\Volo.Abp.Json.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy.Abstractions\Volo.Abp.MultiTenancy.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
<ProjectReference Include="..\Volo.Abp.Threading\Volo.Abp.Threading.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />

2
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AbpAuditingModule.cs

@ -15,7 +15,7 @@ namespace Volo.Abp.Auditing
typeof(AbpTimingModule),
typeof(AbpSecurityModule),
typeof(AbpThreadingModule),
typeof(AbpMultiTenancyAbstractionsModule)
typeof(AbpMultiTenancyModule)
)]
public class AbpAuditingModule : AbpModule
{

6
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditLogActionInfo.cs

@ -1,14 +1,12 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Data;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Auditing
{
public class AuditLogActionInfo : IMultiTenant, IHasExtraProperties
[Serializable]
public class AuditLogActionInfo : IHasExtraProperties
{
public Guid? TenantId { get; set; }
public string ServiceName { get; set; }
public string MethodName { get; set; }

7
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditLogInfo.cs

@ -3,12 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Volo.Abp.Data;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Auditing
{
//TODO: Make serializable!
public class AuditLogInfo : IMultiTenant, IHasExtraProperties
[Serializable]
public class AuditLogInfo : IHasExtraProperties
{
public string ApplicationName { get; set; }
@ -18,6 +17,8 @@ namespace Volo.Abp.Auditing
public Guid? TenantId { get; set; }
public string TenantName { get; set; }
public Guid? ImpersonatorUserId { get; set; }
public Guid? ImpersonatorTenantId { get; set; }

15
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingHelper.cs

@ -92,6 +92,7 @@ namespace Volo.Abp.Auditing
{
ApplicationName = Options.ApplicationName,
TenantId = CurrentTenant.Id,
TenantName = CurrentTenant.Name,
UserId = CurrentUser.Id,
UserName = CurrentUser.UserName,
ClientId = CurrentClient.Id,
@ -106,12 +107,20 @@ namespace Volo.Abp.Auditing
return auditInfo;
}
public virtual AuditLogActionInfo CreateAuditLogAction(Type type, MethodInfo method, object[] arguments)
public virtual AuditLogActionInfo CreateAuditLogAction(
AuditLogInfo auditLog,
Type type,
MethodInfo method,
object[] arguments)
{
return CreateAuditLogAction(type, method, CreateArgumentsDictionary(method, arguments));
return CreateAuditLogAction(auditLog, type, method, CreateArgumentsDictionary(method, arguments));
}
public virtual AuditLogActionInfo CreateAuditLogAction(Type type, MethodInfo method, IDictionary<string, object> arguments)
public virtual AuditLogActionInfo CreateAuditLogAction(
AuditLogInfo auditLog,
Type type,
MethodInfo method,
IDictionary<string, object> arguments)
{
var actionInfo = new AuditLogActionInfo
{

12
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/AuditingInterceptor.cs

@ -49,7 +49,7 @@ namespace Volo.Abp.Auditing
{
if (!ShouldIntercept(invocation, out var auditLog, out var auditLogAction))
{
invocation.Proceed();
await invocation.ProceedAsync();
return;
}
@ -72,7 +72,10 @@ namespace Volo.Abp.Auditing
}
}
protected virtual bool ShouldIntercept(IAbpMethodInvocation invocation, out AuditLogInfo auditLog, out AuditLogActionInfo auditLogAction)
protected virtual bool ShouldIntercept(
IAbpMethodInvocation invocation,
out AuditLogInfo auditLog,
out AuditLogActionInfo auditLogAction)
{
auditLog = null;
auditLogAction = null;
@ -95,7 +98,10 @@ namespace Volo.Abp.Auditing
auditLog = auditLogScope.Log;
auditLogAction = _auditingHelper.CreateAuditLogAction(
invocation.TargetObject.GetType(), invocation.Method, invocation.Arguments
auditLog,
invocation.TargetObject.GetType(),
invocation.Method,
invocation.Arguments
);
return true;

13
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityChangeInfo.cs

@ -2,22 +2,27 @@
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Data;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Auditing
{
public class EntityChangeInfo : IMultiTenant, IHasExtraProperties
[Serializable]
public class EntityChangeInfo : IHasExtraProperties
{
public DateTime ChangeTime { get; set; }
public EntityChangeType ChangeType { get; set; }
/// <summary>
/// TenantId of the related entity.
/// This is not the TenantId of the audit log entry.
/// There can be multiple tenant data changes in a single audit log entry.
/// </summary>
public Guid? EntityTenantId { get; set; }
public string EntityId { get; set; }
public string EntityTypeFullName { get; set; }
public Guid? TenantId { get; set; }
public List<EntityPropertyChangeInfo> PropertyChanges { get; set; }
public Dictionary<string, object> ExtraProperties { get; }

6
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/EntityPropertyChangeInfo.cs

@ -1,9 +1,9 @@
using System;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Auditing
{
public class EntityPropertyChangeInfo : IMultiTenant
[Serializable]
public class EntityPropertyChangeInfo
{
/// <summary>
/// Maximum length of <see cref="PropertyName"/> property.
@ -23,8 +23,6 @@ namespace Volo.Abp.Auditing
/// </summary>
public const int MaxPropertyTypeFullNameLength = 192;
public Guid? TenantId { get; set; }
public virtual string NewValue { get; set; }
public virtual string OriginalValue { get; set; }

14
framework/src/Volo.Abp.Auditing/Volo/Abp/Auditing/IAuditingHelper.cs

@ -11,8 +11,18 @@ namespace Volo.Abp.Auditing
AuditLogInfo CreateAuditLogInfo();
AuditLogActionInfo CreateAuditLogAction(Type type, MethodInfo method, object[] arguments);
AuditLogActionInfo CreateAuditLogAction(
AuditLogInfo auditLog,
Type type,
MethodInfo method,
object[] arguments
);
AuditLogActionInfo CreateAuditLogAction(Type type, MethodInfo method, IDictionary<string, object> arguments);
AuditLogActionInfo CreateAuditLogAction(
AuditLogInfo auditLog,
Type type,
MethodInfo method,
IDictionary<string, object> arguments
);
}
}

1
framework/src/Volo.Abp.Authorization/Volo.Abp.Authorization.csproj

@ -19,6 +19,7 @@
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization.Abstractions\Volo.Abp.Localization.Abstractions.csproj" />
<ProjectReference Include="..\Volo.Abp.MultiTenancy\Volo.Abp.MultiTenancy.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
</ItemGroup>

4
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AbpAuthorizationModule.cs

@ -5,13 +5,15 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security;
namespace Volo.Abp.Authorization
{
[DependsOn(
typeof(AbpSecurityModule),
typeof(AbpLocalizationAbstractionsModule)
typeof(AbpLocalizationAbstractionsModule),
typeof(AbpMultiTenancyModule)
)]
public class AbpAuthorizationModule : AbpModule
{

2
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/AuthorizationInterceptor.cs

@ -35,7 +35,7 @@ namespace Volo.Abp.Authorization
return;
}
AsyncHelper.RunSync(() => AuthorizeAsync(invocation));
await AuthorizeAsync(invocation);
await invocation.ProceedAsync();
}

6
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/IPermissionDefinitionContext.cs

@ -1,5 +1,6 @@
using JetBrains.Annotations;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Authorization.Permissions
{
@ -8,7 +9,10 @@ namespace Volo.Abp.Authorization.Permissions
//TODO: Add Get methods to find and modify a permission or group.
PermissionGroupDefinition GetGroupOrNull(string name);
PermissionGroupDefinition AddGroup([NotNull] string name, ILocalizableString displayName = null);
PermissionGroupDefinition AddGroup(
[NotNull] string name,
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both);
void RemoveGroup(string name);
}

23
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionChecker.cs

@ -4,8 +4,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Security.Principal;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Authorization.Permissions
@ -18,6 +20,8 @@ namespace Volo.Abp.Authorization.Permissions
protected ICurrentPrincipalAccessor PrincipalAccessor { get; }
protected ICurrentTenant CurrentTenant { get; }
protected PermissionOptions Options { get; }
private readonly Lazy<List<IPermissionValueProvider>> _lazyProviders;
@ -26,10 +30,12 @@ namespace Volo.Abp.Authorization.Permissions
IOptions<PermissionOptions> options,
IServiceProvider serviceProvider,
ICurrentPrincipalAccessor principalAccessor,
IPermissionDefinitionManager permissionDefinitionManager)
IPermissionDefinitionManager permissionDefinitionManager,
ICurrentTenant currentTenant)
{
PrincipalAccessor = principalAccessor;
PermissionDefinitionManager = permissionDefinitionManager;
CurrentTenant = currentTenant;
Options = options.Value;
_lazyProviders = new Lazy<List<IPermissionValueProvider>>(
@ -50,13 +56,18 @@ namespace Volo.Abp.Authorization.Permissions
{
Check.NotNull(name, nameof(name));
var context = new PermissionValueCheckContext(
PermissionDefinitionManager.Get(name),
claimsPrincipal
);
var permission = PermissionDefinitionManager.Get(name);
var isGranted = false;
var multiTenancySide = claimsPrincipal?.GetMultiTenancySide()
?? CurrentTenant.GetMultiTenancySide();
if (!permission.MultiTenancySide.HasFlag(multiTenancySide))
{
return false;
}
var isGranted = false;
var context = new PermissionValueCheckContext(permission, claimsPrincipal);
foreach (var provider in ValueProviders)
{
if (context.Permission.Providers.Any() &&

19
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs

@ -2,6 +2,7 @@
using System.Collections.Immutable;
using JetBrains.Annotations;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.Authorization.Permissions
{
@ -18,6 +19,12 @@ namespace Volo.Abp.Authorization.Permissions
/// </summary>
public PermissionDefinition Parent { get; private set; }
/// <summary>
/// MultiTenancy side.
/// Default: <see cref="MultiTenancySides.Both"/>
/// </summary>
public MultiTenancySides MultiTenancySide { get; set; }
/// <summary>
/// A list of allowed providers to get/set value of this permission.
/// An empty list indicates that all providers are allowed.
@ -55,10 +62,12 @@ namespace Volo.Abp.Authorization.Permissions
protected internal PermissionDefinition(
[NotNull] string name,
ILocalizableString displayName = null)
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both)
{
Name = Check.NotNull(name, nameof(name));
DisplayName = displayName ?? new FixedLocalizableString(name);
MultiTenancySide = multiTenancySide;
Properties = new Dictionary<string, object>();
Providers = new List<string>();
@ -67,9 +76,13 @@ namespace Volo.Abp.Authorization.Permissions
public virtual PermissionDefinition AddChild(
[NotNull] string name,
ILocalizableString displayName = null)
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both)
{
var child = new PermissionDefinition(name, displayName)
var child = new PermissionDefinition(
name,
displayName,
multiTenancySide)
{
Parent = this
};

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save