Browse Source

Merge branch 'dev' into auto-merge/rel-5-0/680

pull/10847/head
berkansasmaz 5 years ago
parent
commit
6a03fe9bf6
No known key found for this signature in database GPG Key ID: 884D815C3F32BE00
  1. 137
      .editorconfig
  2. 2
      .gitignore
  3. 6
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en-GB.json
  4. 7
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  5. 6
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json
  6. 10
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  7. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json
  8. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json
  9. 5
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json
  10. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
  11. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json
  12. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json
  13. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json
  14. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json
  15. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json
  16. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json
  17. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
  18. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json
  19. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json
  20. 18
      docs/en/Blog-Posts/2021-11-18 v5_0_Preview/POST.md
  21. BIN
      docs/en/Blog-Posts/2021-11-18 v5_0_Preview/community-talks.png
  22. BIN
      docs/en/Blog-Posts/2021-11-18 v5_0_Preview/cover-50.png
  23. 1671
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md
  24. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-contracts-folder-structure.png
  25. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-final-demo.gif
  26. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-folder-structure.png
  27. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-create.gif
  28. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-creation-modal.png
  29. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-update-modal.png
  30. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/demo.png
  31. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-file-structure.png
  32. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-shared-file-structure.png
  33. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/er-diagram.png
  34. BIN
      docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/web-folder-structure.png
  35. 2
      docs/en/Customizing-Application-Modules-Extending-Entities.md
  36. 2
      docs/en/Virtual-File-System.md
  37. 1
      docs/zh-Hans/Background-Workers.md
  38. 11
      framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/AbpApiVersioningAbstractionsModule.cs
  39. 9
      framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs
  40. 19
      framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs
  41. 25
      framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Microsoft/AspNetCore/Builder/ApplicationBuilderAbpJwtTokenMiddlewareExtension.cs
  42. 9
      framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo/Abp/AspNetCore/Authentication/JwtBearer/AbpAspNetCoreAuthenticationJwtBearerModule.cs
  43. 85
      framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs
  44. 9
      framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/AbpAspNetCoreAuthenticationOAuthModule.cs
  45. 71
      framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs
  46. 41
      framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/RemoveDuplicateClaimAction.cs
  47. 81
      framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs
  48. 13
      framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo/Abp/AspNetCore/Authentication/OpenIdConnect/AbpAspNetCoreAuthenticationOpenIdConnectModule.cs
  49. 53
      framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/AbpAspNetCoreComponentsServerThemingModule.cs
  50. 21
      framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalBundles.cs
  51. 13
      framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalScriptContributor.cs
  52. 25
      framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalStyleContributor.cs
  53. 76
      framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/AbpAspNetCoreComponentsServerModule.cs
  54. 37
      framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs
  55. 119
      framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Extensibility/BlazorServerLookupApiRequestService.cs
  56. 19
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/AbpAspNetCoreComponentsWebThemingModule.cs
  57. 95
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs
  58. 9
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/IPageToolbarContributor.cs
  59. 9
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/IPageToolbarManager.cs
  60. 15
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbar.cs
  61. 25
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarContributionContext.cs
  62. 9
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarContributor.cs
  63. 7
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarContributorList.cs
  64. 7
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarDictionary.cs
  65. 97
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarExtensions.cs
  66. 33
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarItem.cs
  67. 7
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarItemList.cs
  68. 39
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarManager.cs
  69. 63
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/SimplePageToolbarContributor.cs
  70. 17
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Routing/AbpRouterOptions.cs
  71. 11
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Routing/RouterAssemblyList.cs
  72. 17
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/AbpToolbarOptions.cs
  73. 27
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarConfigurationContext.cs
  74. 11
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarContributor.cs
  75. 9
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarManager.cs
  76. 11
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/StandardToolbars.cs
  77. 19
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/Toolbar.cs
  78. 65
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarConfigurationContext.cs
  79. 30
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarItem.cs
  80. 43
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarManager.cs
  81. 17
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpAspNetCoreApplicationCreationOptions.cs
  82. 25
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpAspNetCoreComponentsWebModule.cs
  83. 123
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorClientHttpMessageHandler.cs
  84. 57
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs
  85. 87
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpUtilsService.cs
  86. 17
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Alerts/AlertManager.cs
  87. 11
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs
  88. 13
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs
  89. 15
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieOptions.cs
  90. 43
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieService.cs
  91. 13
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DefaultServerUrlProvider.cs
  92. 13
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DependencyInjection/ComponentsClientScopeServiceProviderAccessor.cs
  93. 87
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLogger.cs
  94. 43
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLoggerProvider.cs
  95. 91
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs
  96. 25
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityAction.cs
  97. 13
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityActionDictionary.cs
  98. 11
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/ILookupApiRequestService.cs
  99. 37
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumn.cs
  100. 13
      framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumnDictionary.cs

137
.editorconfig

@ -0,0 +1,137 @@
# EditorConfig is awesome: https://EditorConfig.org
# Please feel free to update it (by considering the code style of ABP Team).
# top-most EditorConfig file
root = true
[*.cs]
#Namespace settings
csharp_style_namespace_declarations = file_scoped
dotnet_diagnostic.IDE0161.severity = warning
#Core editorconfig formatting - indentation
#use tabs for indentation
indent_style = tabs
#Formatting - indentation options
#indent switch case contents.
csharp_indent_case_contents = true
#indent switch labels
csharp_indent_switch_labels = true
#Formatting - new line options
#place catch statements on a new line
csharp_new_line_before_catch = true
#place else statements on a new line
csharp_new_line_before_else = true
#require members of object intializers to be on separate lines
csharp_new_line_before_members_in_object_initializers = true
#require braces to be on a new line for object_collection_array_initializers, methods, control_blocks, types, and lambdas (also known as "Allman" style)
csharp_new_line_before_open_brace = object_collection_array_initializers, methods, control_blocks, types, lambdas
#Formatting - organize using options
#sort System.* using directives alphabetically, and place them before other usings
dotnet_sort_system_directives_first = true
#Formatting - spacing options
#require NO space between a cast and the value
csharp_space_after_cast = false
#require a space before the colon for bases or interfaces in a type declaration
csharp_space_after_colon_in_inheritance_clause = true
#require a space after a keyword in a control flow statement such as a for loop
csharp_space_after_keywords_in_control_flow_statements = true
#require a space before the colon for bases or interfaces in a type declaration
csharp_space_before_colon_in_inheritance_clause = true
#remove space within empty argument list parentheses
csharp_space_between_method_call_empty_parameter_list_parentheses = false
#remove space between method call name and opening parenthesis
csharp_space_between_method_call_name_and_opening_parenthesis = false
#do not place space characters after the opening parenthesis and before the closing parenthesis of a method call
csharp_space_between_method_call_parameter_list_parentheses = false
#remove space within empty parameter list parentheses for a method declaration
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
#place a space character after the opening parenthesis and before the closing parenthesis of a method declaration parameter list.
csharp_space_between_method_declaration_parameter_list_parentheses = false
#Formatting - wrapping options
#leave code block on single line
csharp_preserve_single_line_blocks = true
#Style - Code block preferences
#prefer curly braces even for one line of code
csharp_prefer_braces = true:suggestion
#Style - expression bodied member options
#prefer block bodies for constructors
csharp_style_expression_bodied_constructors = false:suggestion
#prefer block bodies for methods
csharp_style_expression_bodied_methods = false:suggestion
#prefer expression-bodied members for properties
csharp_style_expression_bodied_properties = true:suggestion
#Style - expression level options
#prefer out variables to be declared inline in the argument list of a method call when possible
csharp_style_inlined_variable_declaration = true:suggestion
#prefer the language keyword for member access expressions, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_member_access = true:suggestion
#Style - Expression-level preferences
#prefer default over default(T)
csharp_prefer_simple_default_expression = true:suggestion
#prefer objects to be initialized using object initializers when possible
dotnet_style_object_initializer = true:suggestion
#prefer inferred tuple element names
dotnet_style_prefer_inferred_tuple_names = true:suggestion
#Style - implicit and explicit types
#prefer var over explicit type in all cases, unless overridden by another code style rule
csharp_style_var_elsewhere = true:suggestion
#prefer var is used to declare variables with built-in system types such as int
csharp_style_var_for_built_in_types = true:suggestion
#prefer var when the type is already mentioned on the right-hand side of a declaration expression
csharp_style_var_when_type_is_apparent = true:suggestion
#Style - language keyword and framework type options
#prefer the language keyword for local variables, method parameters, and class members, instead of the type name, for types that have a keyword to represent them
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
#Style - Miscellaneous preferences
#prefer local functions over anonymous functions
csharp_style_pattern_local_over_anonymous_function = true:suggestion
#Style - modifier options
#prefer accessibility modifiers to be declared except for public interface members. This will currently not differ from always and will act as future proofing for if C# adds default interface methods.
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
#Style - Modifier preferences
#when this rule is set to a list of modifiers, prefer the specified ordering.
csharp_preferred_modifier_order = public,protected,private,virtual,async,readonly,static,override,abstract:suggestion
#Style - Pattern matching
#prefer pattern matching instead of is expression with type casts
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
#Style - qualification options
#prefer fields not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_field = false:suggestion
#prefer methods not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_method = false:suggestion
#prefer properties not to be prefaced with this. or Me. in Visual Basic
dotnet_style_qualification_for_property = false:suggestion

2
.gitignore

@ -6,7 +6,7 @@
*.user *.user
*.userosscache *.userosscache
*.sln.docstates *.sln.docstates
*.editorconfig
# User-specific files (MonoDevelop/Xamarin Studio) # User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs *.userprefs

6
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en-GB.json

@ -210,6 +210,10 @@
"Completed": "Completed", "Completed": "Completed",
"Failed": "Failed", "Failed": "Failed",
"PaymentRequestDeletionWarningMessage": "This payment request will be deleted. Do you confirm that?", "PaymentRequestDeletionWarningMessage": "This payment request will be deleted. Do you confirm that?",
"Payment": "Payment" "Payment": "Payment",
"Permission:SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmailWarningMessage": "Are you sure you want to send welcome email to the organization members?",
"SendWelcomeEmailSuccessMessage": "Welcome email sent successfully!"
} }
} }

7
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -352,6 +352,11 @@
"Volo.AbpIo.Commercial:030008": "Purchase date can be set only when status is Purchased!", "Volo.AbpIo.Commercial:030008": "Purchase date can be set only when status is Purchased!",
"Volo.AbpIo.Commercial:030009": "User not found!", "Volo.AbpIo.Commercial:030009": "User not found!",
"Volo.AbpIo.Commercial:030010": "To purchase the trial license, first you need to activate your trial license!", "Volo.AbpIo.Commercial:030010": "To purchase the trial license, first you need to activate your trial license!",
"Volo.AbpIo.Commercial:030011": "You cannot delete a trial license when it is purchased!" "Volo.AbpIo.Commercial:030011": "You cannot delete a trial license when it is purchased!",
"Permission:SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmail": "Send Welcome Email",
"SendWelcomeEmailWarningMessage": "Are you sure you want to send welcome email to the organization members?",
"SendWelcomeEmailSuccessMessage": "Welcome email sent successfully!",
"PaymentRequestId": "Payment Request Id"
} }
} }

6
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json

@ -348,6 +348,10 @@
"Volo.AbpIo.Commercial:030008": "Satın alma tarihi yalnızca durum Satın Alındı olduğunda ayarlanabilir!", "Volo.AbpIo.Commercial:030008": "Satın alma tarihi yalnızca durum Satın Alındı olduğunda ayarlanabilir!",
"Volo.AbpIo.Commercial:030009": "Kullanıcı bulunamadı!", "Volo.AbpIo.Commercial:030009": "Kullanıcı bulunamadı!",
"Volo.AbpIo.Commercial:030010": "Deneme lisansını satın almak için önce deneme lisansınızı etkinleştirmeniz gerekir!", "Volo.AbpIo.Commercial:030010": "Deneme lisansını satın almak için önce deneme lisansınızı etkinleştirmeniz gerekir!",
"Volo.AbpIo.Commercial:030011": "Satın alındığında bir deneme lisansını silemezsiniz!" "Volo.AbpIo.Commercial:030011": "Satın alındığında bir deneme lisansını silemezsiniz!",
"Permission:SendWelcomeEmail": "Hoşgeldin Emaili Gönder",
"SendWelcomeEmail": "Hoşgeldin Emaili Gönder",
"SendWelcomeEmailWarningMessage": "Organizasyon üyelerine hoşgeldin emaili göndermek istediğinden emin misin?",
"SendWelcomeEmailSuccessMessage": "Hoşgeldin emaili başarıyla gönderilmiştir!"
} }
} }

10
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json

@ -178,7 +178,7 @@
"ChangingLicenseType": "Can I upgrade my license type later?", "ChangingLicenseType": "Can I upgrade my license type later?",
"ChangingLicenseTypeExplanation": "You can upgrade to a higher license by paying the difference within your active license period. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date. Besides, you can also add new developer seats to your existing license, see \"How many developers can work on the ABP Commercial?\"", "ChangingLicenseTypeExplanation": "You can upgrade to a higher license by paying the difference within your active license period. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date. Besides, you can also add new developer seats to your existing license, see \"How many developers can work on the ABP Commercial?\"",
"LicenseExtendUpgradeDiff": "What is the difference between license extend and upgrade?", "LicenseExtendUpgradeDiff": "What is the difference between license extend and upgrade?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.<hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.", "LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development. When you extend your license, 1 year is added to your license expiry date. <hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "What is the license renewal cost after 1 year?", "LicenseRenewalCost": "What is the license renewal cost after 1 year?",
"LicenseRenewalCostExplanation": "The renewal (extend) rate of all ABP Commercial perpetual licenses is {0} of the license list price. The renewal price of the standard Team License is ${1}, standard Business License is ${2} and standard Enterprise License is ${3}. If you are already a customer, <a href='{4}' target='_blank'>log into your account</a> to review the available renewal pricing.", "LicenseRenewalCostExplanation": "The renewal (extend) rate of all ABP Commercial perpetual licenses is {0} of the license list price. The renewal price of the standard Team License is ${1}, standard Business License is ${2} and standard Enterprise License is ${3}. If you are already a customer, <a href='{4}' target='_blank'>log into your account</a> to review the available renewal pricing.",
"HowDoIRenewMyLicense": "How do I renew my license?", "HowDoIRenewMyLicense": "How do I renew my license?",
@ -390,6 +390,10 @@
"TrialLicenseExpireMessage": "You are using the trial license and your trial license will expire on {0}.", "TrialLicenseExpireMessage": "You are using the trial license and your trial license will expire on {0}.",
"TryForFree": "Try For Free", "TryForFree": "Try For Free",
"TrialLicenseExpiredInfo": "Your trial license period has expired!", "TrialLicenseExpiredInfo": "Your trial license period has expired!",
"CommercialNewsletterConfirmationMessage": "I agree to the <a href=\"https://commercial.abp.io/TermsConditions\">Terms & Conditions</a> and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>." "CommercialNewsletterConfirmationMessage": "I agree to the <a href=\"https://commercial.abp.io/TermsConditions\">Terms & Conditions</a> and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>.",
} "DowngradeLicensePlan": "Can I downgrade to a lower license plan in the future?",
"DowngradeLicensePlanExplanation": "You cannot downgrade your existing license plan. But you can purchase a new lower license plan and continue to your development on the new license. After you purchase a lower license, you just need to login to your new license plan via ABP CLI command: ` abp login <username> -o <organization> `.",
"LicenseTransfer": "Can a license be transferred from one developer to another?",
"LicenseTransferExplanation": "Yes! When you purchase a license, you become the license holder, hence you will have access to the organization management page. An organization has owner and developer roles. Owners can manage the developer seats and assign developers. Each assigned developer will login via ABP CLI command into the system and will have development and support permissions."
}
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ar.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "يجب عليك إدخال 3 أحرف على الأقل!", "MinimumSearchContent": "يجب عليك إدخال 3 أحرف على الأقل!",
"Volo.AbpIo.Domain:060001": "عنوان URL المصدر (\"{ArticleUrl}\") ليس عنوان URL لـ Github", "Volo.AbpIo.Domain:060001": "عنوان URL المصدر (\"{ArticleUrl}\") ليس عنوان URL لـ Github",
"Volo.AbpIo.Domain:060002": "محتوى المقالة غير متوفر من مورد Github (\"{ArticleUrl}\").", "Volo.AbpIo.Domain:060002": "محتوى المقالة غير متوفر من مورد Github (\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "لم يتم العثور على محتوى مقال!" "Volo.AbpIo.Domain:060003": "لم يتم العثور على محتوى مقال!",
"SeeMore": "شاهد المزيد"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/de-DE.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Sie müssen mindestens 3 Zeichen eingeben!", "MinimumSearchContent": "Sie müssen mindestens 3 Zeichen eingeben!",
"Volo.AbpIo.Domain:060001": "Quell-URL(\"{ArticleUrl}\") ist keine Github-URL", "Volo.AbpIo.Domain:060001": "Quell-URL(\"{ArticleUrl}\") ist keine Github-URL",
"Volo.AbpIo.Domain:060002": "Artikelinhalt ist über die Github(\"{ArticleUrl}\")-Ressource nicht verfügbar.", "Volo.AbpIo.Domain:060002": "Artikelinhalt ist über die Github(\"{ArticleUrl}\")-Ressource nicht verfügbar.",
"Volo.AbpIo.Domain:060003": "Kein Artikelinhalt gefunden!" "Volo.AbpIo.Domain:060003": "Kein Artikelinhalt gefunden!",
"SeeMore": "Mehr Sehen"
} }
} }

5
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en-GB.json

@ -101,6 +101,7 @@
"ArticleRequestMessageTitle": "<a href=\"https://github.com/abpframework/abp/issues/new\">Open an issue</a> on the GitHub to request an article/tutorial you want to see on this web site.", "ArticleRequestMessageTitle": "<a href=\"https://github.com/abpframework/abp/issues/new\">Open an issue</a> on the GitHub to request an article/tutorial you want to see on this web site.",
"ArticleRequestMessageBody": "Here is the list of the requested articles by the Community. Do you want to write a requested article? Please click on the request and join the discussion.", "ArticleRequestMessageBody": "Here is the list of the requested articles by the Community. Do you want to write a requested article? Please click on the request and join the discussion.",
"Language": "Language", "Language": "Language",
"CreateArticleLanguageInfo": "The language in which the article is written" "CreateArticleLanguageInfo": "Language of the article",
"SeeMore": "See More"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "You must enter at least 3 characters!", "MinimumSearchContent": "You must enter at least 3 characters!",
"Volo.AbpIo.Domain:060001": "Source URL(\"{ArticleUrl}\") is not Github URL", "Volo.AbpIo.Domain:060001": "Source URL(\"{ArticleUrl}\") is not Github URL",
"Volo.AbpIo.Domain:060002": "Article Content is not available from Github(\"{ArticleUrl}\") resource.", "Volo.AbpIo.Domain:060002": "Article Content is not available from Github(\"{ArticleUrl}\") resource.",
"Volo.AbpIo.Domain:060003": "No article content found!" "Volo.AbpIo.Domain:060003": "No article content found!",
"SeeMore": "See More"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/es.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "¡Debes ingresar al menos 3 caracteres!", "MinimumSearchContent": "¡Debes ingresar al menos 3 caracteres!",
"Volo.AbpIo.Domain:060001": "La URL de origen (\"{ArticleUrl}\") no es la URL de Github", "Volo.AbpIo.Domain:060001": "La URL de origen (\"{ArticleUrl}\") no es la URL de Github",
"Volo.AbpIo.Domain:060002": "El contenido del artículo no está disponible en el recurso de Github (\"{ArticleUrl}\").", "Volo.AbpIo.Domain:060002": "El contenido del artículo no está disponible en el recurso de Github (\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "¡No se encontró contenido del artículo!" "Volo.AbpIo.Domain:060003": "¡No se encontró contenido del artículo!",
"SeeMore": "Ver Más"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fi.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Sinun on annettava vähintään 3 merkkiä!", "MinimumSearchContent": "Sinun on annettava vähintään 3 merkkiä!",
"Volo.AbpIo.Domain:060001": "Lähteen URL-osoite (\"{ArticleUrl}\") ei ole Githubin URL-osoite", "Volo.AbpIo.Domain:060001": "Lähteen URL-osoite (\"{ArticleUrl}\") ei ole Githubin URL-osoite",
"Volo.AbpIo.Domain:060002": "Artikkelin sisältö ei ole saatavilla Githubin (\"{ArticleUrl}\") -resurssista.", "Volo.AbpIo.Domain:060002": "Artikkelin sisältö ei ole saatavilla Githubin (\"{ArticleUrl}\") -resurssista.",
"Volo.AbpIo.Domain:060003": "Artikkelin sisältöä ei löytynyt!" "Volo.AbpIo.Domain:060003": "Artikkelin sisältöä ei löytynyt!",
"SeeMore": "Katso Lisää"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/fr.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Vous devez saisir au moins 3 caractères!", "MinimumSearchContent": "Vous devez saisir au moins 3 caractères!",
"Volo.AbpIo.Domain:060001": "L'URL source (\"{ArticleUrl}\") n'est pas une URL Github", "Volo.AbpIo.Domain:060001": "L'URL source (\"{ArticleUrl}\") n'est pas une URL Github",
"Volo.AbpIo.Domain:060002": "Le contenu de l'article n'est pas disponible à partir de la ressource Github(\"{ArticleUrl}\").", "Volo.AbpIo.Domain:060002": "Le contenu de l'article n'est pas disponible à partir de la ressource Github(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Aucun contenu d'article trouvé !" "Volo.AbpIo.Domain:060003": "Aucun contenu d'article trouvé !",
"SeeMore": "Voir Plus"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/hi.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "आपको कम से कम 3 वर्ण दर्ज करने होंगे!", "MinimumSearchContent": "आपको कम से कम 3 वर्ण दर्ज करने होंगे!",
"Volo.AbpIo.Domain:060001": "स्रोत URL (\"{ArticleUrl}\") जीथब URL नहीं है", "Volo.AbpIo.Domain:060001": "स्रोत URL (\"{ArticleUrl}\") जीथब URL नहीं है",
"Volo.AbpIo.Domain:060002": "लेख सामग्री Github (\"{ArticleUrl}\") संसाधन से उपलब्ध नहीं है।", "Volo.AbpIo.Domain:060002": "लेख सामग्री Github (\"{ArticleUrl}\") संसाधन से उपलब्ध नहीं है।",
"Volo.AbpIo.Domain:060003": "कोई लेख सामग्री नहीं मिली!" "Volo.AbpIo.Domain:060003": "कोई लेख सामग्री नहीं मिली!",
"SeeMore": "और देखें"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/is.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Þú verður að slá inn að minnsta kosti 3 stafi!", "MinimumSearchContent": "Þú verður að slá inn að minnsta kosti 3 stafi!",
"Volo.AbpIo.Domain:060001": "Upprunaslóð (\"{ArticleUrl} \") er ekki Github slóð", "Volo.AbpIo.Domain:060001": "Upprunaslóð (\"{ArticleUrl} \") er ekki Github slóð",
"Volo.AbpIo.Domain:060002": "Innihald greinar er ekki fáanlegt frá Github (\"{ArticleUrl} \") resoursum.", "Volo.AbpIo.Domain:060002": "Innihald greinar er ekki fáanlegt frá Github (\"{ArticleUrl} \") resoursum.",
"Volo.AbpIo.Domain:060003": "Innihald greinar fannst ekki!" "Volo.AbpIo.Domain:060003": "Innihald greinar fannst ekki!",
"SeeMore": "Sjá Meira"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/it.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Devi inserire almeno 3 caratteri!", "MinimumSearchContent": "Devi inserire almeno 3 caratteri!",
"Volo.AbpIo.Domain:060001": "Source URL(\"{ArticleUrl}\") non è un URL di GitHub", "Volo.AbpIo.Domain:060001": "Source URL(\"{ArticleUrl}\") non è un URL di GitHub",
"Volo.AbpIo.Domain:060002": "Il contenuto dell'articolo non è disponibile dalla risorsa Github(\"{ArticleUrl}\").", "Volo.AbpIo.Domain:060002": "Il contenuto dell'articolo non è disponibile dalla risorsa Github(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Nessun contenuto dell'articolo trovato!" "Volo.AbpIo.Domain:060003": "Nessun contenuto dell'articolo trovato!",
"SeeMore": "Vedi Altro"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Trebuie să introduceţi cel putin 3 caractere!", "MinimumSearchContent": "Trebuie să introduceţi cel putin 3 caractere!",
"Volo.AbpIo.Domain:060001": "Sursa URL(\"{ArticleUrl}\") nu este URL GitHub", "Volo.AbpIo.Domain:060001": "Sursa URL(\"{ArticleUrl}\") nu este URL GitHub",
"Volo.AbpIo.Domain:060002": "Conţinutul articolului nu este disponibil din resursa de pe GitHub(\"{ArticleUrl}\").", "Volo.AbpIo.Domain:060002": "Conţinutul articolului nu este disponibil din resursa de pe GitHub(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Nu a fost găsit conţinutul articolului!" "Volo.AbpIo.Domain:060003": "Nu a fost găsit conţinutul articolului!",
"SeeMore": "Vezi mai mult"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/sk.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "Musíte zadať aspoň 3 znaky!", "MinimumSearchContent": "Musíte zadať aspoň 3 znaky!",
"Volo.AbpIo.Domain:060001": "Zdrojová URL(\"{ArticleUrl}\") nie je URL Githubu", "Volo.AbpIo.Domain:060001": "Zdrojová URL(\"{ArticleUrl}\") nie je URL Githubu",
"Volo.AbpIo.Domain:060002": "Obsah článku nie je dostupný v Github zdroji(\"{ArticleUrl}\").", "Volo.AbpIo.Domain:060002": "Obsah článku nie je dostupný v Github zdroji(\"{ArticleUrl}\").",
"Volo.AbpIo.Domain:060003": "Nenašiel sa žiadny obsah článku!" "Volo.AbpIo.Domain:060003": "Nenašiel sa žiadny obsah článku!",
"SeeMore": "Vidět Víc"
} }
} }

3
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json

@ -142,6 +142,7 @@
"MinimumSearchContent": "您必须输入至少 3 个字符!", "MinimumSearchContent": "您必须输入至少 3 个字符!",
"Volo.AbpIo.Domain:060001": "源 URL(\"{ArticleUrl}\") 不是 Github URL", "Volo.AbpIo.Domain:060001": "源 URL(\"{ArticleUrl}\") 不是 Github URL",
"Volo.AbpIo.Domain:060002": "文章内容无法从 Github(\"{ArticleUrl}\") 资源中获得。", "Volo.AbpIo.Domain:060002": "文章内容无法从 Github(\"{ArticleUrl}\") 资源中获得。",
"Volo.AbpIo.Domain:060003": "没有找到文章内容!" "Volo.AbpIo.Domain:060003": "没有找到文章内容!",
"SeeMore": "查看更多"
} }
} }

18
docs/en/Blog-Posts/2021-11-18 v5_0_Preview/POST.md

@ -127,13 +127,7 @@ First of all, you need to have EF Core or MongoDB installed into your solution.
#### Install the packages #### Install the packages
Install the new [Volo.Abp.EventBus.Boxes](https://www.nuget.org/packages/Volo.Abp.EventBus.Boxes) NuGet package to your database layer (to `EntityFrameworkCore` or `MongoDB` project) or to the host application. Open a command-line terminal at the root directory of your database (or host) project and execute the following command: For the outbox & inbox functionality, ABP depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations), including Redis, SqlServer and ZooKeeper. You can use the one you like. Here, I will show the Redis provider.
````csharp
abp add-package Volo.Abp.EventBus.Boxes
````
This will install the package and setup the ABP module dependency. This package depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations), including Redis, SqlServer and ZooKeeper. You can use the one you like. Here, I will show the Redis provider.
Add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class: Add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class:
@ -285,6 +279,16 @@ This can be a breaking change in rare cases (for example, if you create host sid
## Community News ## Community News
### ABP Community Talks 2021.12
![community-talks](community-talks.png)
As the core ABP development team, we've decided to organize monthly live meetings with the ABP community. The first live meeting will be at **December 16, 2021, 17:00 (UTC)** on YouTube. ABP core team members will present some of the new features coming with ABP 5.0.
**Join this event on the Kommunity platform: https://kommunity.com/volosoft/events/abp-community-talks-4afca9c9**
You can also [subscribe to the Volosoft channel](https://www.youtube.com/channel/UCO3XKlpvq8CA5MQNVS6b3dQ) for reminders for further ABP events and videos.
### ABP was on ASP.NET Community Startup! ### ABP was on ASP.NET Community Startup!
It was great for us to be invited to Microsoft's [ASP.NET Community Weekly Standup](https://dotnet.microsoft.com/live/community-standup) show, at September 28. There was a very high attention and that made us very happy. Thanks to the ABP Community and all the watchers :) If you've missed the talk, [you can watch it here](https://www.youtube.com/watch?v=vMWM-_ihjwM). It was great for us to be invited to Microsoft's [ASP.NET Community Weekly Standup](https://dotnet.microsoft.com/live/community-standup) show, at September 28. There was a very high attention and that made us very happy. Thanks to the ABP Community and all the watchers :) If you've missed the talk, [you can watch it here](https://www.youtube.com/watch?v=vMWM-_ihjwM).

BIN
docs/en/Blog-Posts/2021-11-18 v5_0_Preview/community-talks.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 KiB

BIN
docs/en/Blog-Posts/2021-11-18 v5_0_Preview/cover-50.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

1671
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/POST.md

File diff suppressed because it is too large

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-contracts-folder-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-final-demo.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/application-folder-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-create.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-creation-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/book-update-modal.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/demo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-file-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/domain-shared-file-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/er-diagram.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/Community-Articles/2021-10-31-Many-to-Many-Relationship-with-ABP-and-EF-Core/web-folder-structure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

2
docs/en/Customizing-Application-Modules-Extending-Entities.md

@ -63,8 +63,6 @@ You can then use the same extra properties system defined in the previous sectio
Another approach can be **creating your own entity** mapped to **the same database table** (or collection for a MongoDB database). Another approach can be **creating your own entity** mapped to **the same database table** (or collection for a MongoDB database).
`AppUser` entity in the [application startup template](Startup-Templates/Application.md) already implements this approach. [EF Core Migrations document](Entity-Framework-Core-Migrations.md) describes how to implement it and manage **EF Core database migrations** in such a case. It is also possible for MongoDB, while this time you won't deal with the database migration problems.
## Creating a New Entity with Its Own Database Table/Collection ## Creating a New Entity with Its Own Database Table/Collection
Mapping your entity to an **existing table** of a depended module has a few disadvantages; Mapping your entity to an **existing table** of a depended module has a few disadvantages;

2
docs/en/Virtual-File-System.md

@ -119,7 +119,7 @@ The Virtual File System is well integrated to ASP.NET Core:
### Static Virtual File Folders ### Static Virtual File Folders
By default, ASP.NET Core only allows the `wwwroot` folder to contain the static files consumed by the clients. When you use the birtual File System, the following folders also can contain static files: By default, ASP.NET Core only allows the `wwwroot` folder to contain the static files consumed by the clients. When you use the virtual File System, the following folders also can contain static files:
* Pages * Pages
* Views * Views

1
docs/zh-Hans/Background-Workers.md

@ -2,7 +2,6 @@
## 介绍 ## 介绍
背景工人在应用简单独立的线程在后台运行.一般来说,他们定期运行,以执行一些任务.例子;
后台工作者在应用程序后台运行的简单的独立线程,一般来说它们定期运行执行一些任务.例如; 后台工作者在应用程序后台运行的简单的独立线程,一般来说它们定期运行执行一些任务.例如;
* 后台工作者可以定期**删除过时的日志**. * 后台工作者可以定期**删除过时的日志**.

11
framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/AbpApiVersioningAbstractionsModule.cs

@ -1,13 +1,12 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.ApiVersioning namespace Volo.Abp.ApiVersioning;
public class AbpApiVersioningAbstractionsModule : AbpModule
{ {
public class AbpApiVersioningAbstractionsModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context)
{ {
public override void ConfigureServices(ServiceConfigurationContext context) context.Services.AddSingleton<IRequestedApiVersion>(NullRequestedApiVersion.Instance);
{
context.Services.AddSingleton<IRequestedApiVersion>(NullRequestedApiVersion.Instance);
}
} }
} }

9
framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/IRequestedApiVersion.cs

@ -1,7 +1,6 @@
namespace Volo.Abp.ApiVersioning namespace Volo.Abp.ApiVersioning;
public interface IRequestedApiVersion
{ {
public interface IRequestedApiVersion string Current { get; }
{
string Current { get; }
}
} }

19
framework/src/Volo.Abp.ApiVersioning.Abstractions/Volo/Abp/ApiVersioning/NullRequestedApiVersion.cs

@ -1,14 +1,13 @@
namespace Volo.Abp.ApiVersioning namespace Volo.Abp.ApiVersioning;
public class NullRequestedApiVersion : IRequestedApiVersion
{ {
public class NullRequestedApiVersion : IRequestedApiVersion public static NullRequestedApiVersion Instance = new NullRequestedApiVersion();
{
public static NullRequestedApiVersion Instance = new NullRequestedApiVersion();
public string Current => null; public string Current => null;
private NullRequestedApiVersion()
{
private NullRequestedApiVersion()
{
}
} }
} }

25
framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Microsoft/AspNetCore/Builder/ApplicationBuilderAbpJwtTokenMiddlewareExtension.cs

@ -1,25 +1,24 @@
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.AspNetCore.Builder;
public static class ApplicationBuilderAbpJwtTokenMiddlewareExtension
{ {
public static class ApplicationBuilderAbpJwtTokenMiddlewareExtension public static IApplicationBuilder UseJwtTokenMiddleware(this IApplicationBuilder app, string schema = JwtBearerDefaults.AuthenticationScheme)
{ {
public static IApplicationBuilder UseJwtTokenMiddleware(this IApplicationBuilder app, string schema = JwtBearerDefaults.AuthenticationScheme) return app.Use(async (ctx, next) =>
{ {
return app.Use(async (ctx, next) => if (ctx.User.Identity?.IsAuthenticated != true)
{ {
if (ctx.User.Identity?.IsAuthenticated != true) var result = await ctx.AuthenticateAsync(schema);
if (result.Succeeded && result.Principal != null)
{ {
var result = await ctx.AuthenticateAsync(schema); ctx.User = result.Principal;
if (result.Succeeded && result.Principal != null)
{
ctx.User = result.Principal;
}
} }
}
await next(); await next();
}); });
}
} }
} }

9
framework/src/Volo.Abp.AspNetCore.Authentication.JwtBearer/Volo/Abp/AspNetCore/Authentication/JwtBearer/AbpAspNetCoreAuthenticationJwtBearerModule.cs

@ -1,11 +1,10 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Security; using Volo.Abp.Security;
namespace Volo.Abp.AspNetCore.Authentication.JwtBearer namespace Volo.Abp.AspNetCore.Authentication.JwtBearer;
[DependsOn(typeof(AbpSecurityModule))]
public class AbpAspNetCoreAuthenticationJwtBearerModule : AbpModule
{ {
[DependsOn(typeof(AbpSecurityModule))]
public class AbpAspNetCoreAuthenticationJwtBearerModule : AbpModule
{
}
} }

85
framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs

@ -1,57 +1,56 @@
using Volo.Abp.AspNetCore.Authentication.OAuth.Claims; using Volo.Abp.AspNetCore.Authentication.OAuth.Claims;
using Volo.Abp.Security.Claims; using Volo.Abp.Security.Claims;
namespace Microsoft.AspNetCore.Authentication.OAuth.Claims namespace Microsoft.AspNetCore.Authentication.OAuth.Claims;
public static class AbpClaimActionCollectionExtensions
{ {
public static class AbpClaimActionCollectionExtensions public static void MapAbpClaimTypes(this ClaimActionCollection claimActions)
{ {
public static void MapAbpClaimTypes(this ClaimActionCollection claimActions) if (AbpClaimTypes.UserName != "name")
{
claimActions.MapJsonKey(AbpClaimTypes.UserName, "name");
claimActions.DeleteClaim("name");
claimActions.RemoveDuplicate(AbpClaimTypes.UserName);
}
if (AbpClaimTypes.Email != "email")
{
claimActions.MapJsonKey(AbpClaimTypes.Email, "email");
claimActions.DeleteClaim("email");
claimActions.RemoveDuplicate(AbpClaimTypes.Email);
}
if (AbpClaimTypes.EmailVerified != "email_verified")
{
claimActions.MapJsonKey(AbpClaimTypes.EmailVerified, "email_verified");
}
if (AbpClaimTypes.PhoneNumber != "phone_number")
{ {
if (AbpClaimTypes.UserName != "name") claimActions.MapJsonKey(AbpClaimTypes.PhoneNumber, "phone_number");
{
claimActions.MapJsonKey(AbpClaimTypes.UserName, "name");
claimActions.DeleteClaim("name");
claimActions.RemoveDuplicate(AbpClaimTypes.UserName);
}
if (AbpClaimTypes.Email != "email")
{
claimActions.MapJsonKey(AbpClaimTypes.Email, "email");
claimActions.DeleteClaim("email");
claimActions.RemoveDuplicate(AbpClaimTypes.Email);
}
if (AbpClaimTypes.EmailVerified != "email_verified")
{
claimActions.MapJsonKey(AbpClaimTypes.EmailVerified, "email_verified");
}
if (AbpClaimTypes.PhoneNumber != "phone_number")
{
claimActions.MapJsonKey(AbpClaimTypes.PhoneNumber, "phone_number");
}
if (AbpClaimTypes.PhoneNumberVerified != "phone_number_verified")
{
claimActions.MapJsonKey(AbpClaimTypes.PhoneNumberVerified, "phone_number_verified");
}
if (AbpClaimTypes.Role != "role")
{
claimActions.MapJsonKeyMultiple(AbpClaimTypes.Role, "role");
}
claimActions.RemoveDuplicate(AbpClaimTypes.Name);
} }
public static void MapJsonKeyMultiple(this ClaimActionCollection claimActions, string claimType, string jsonKey) if (AbpClaimTypes.PhoneNumberVerified != "phone_number_verified")
{ {
claimActions.Add(new MultipleClaimAction(claimType, jsonKey)); claimActions.MapJsonKey(AbpClaimTypes.PhoneNumberVerified, "phone_number_verified");
} }
public static void RemoveDuplicate(this ClaimActionCollection claimActions, string claimType) if (AbpClaimTypes.Role != "role")
{ {
claimActions.Add(new RemoveDuplicateClaimAction(claimType)); claimActions.MapJsonKeyMultiple(AbpClaimTypes.Role, "role");
} }
claimActions.RemoveDuplicate(AbpClaimTypes.Name);
}
public static void MapJsonKeyMultiple(this ClaimActionCollection claimActions, string claimType, string jsonKey)
{
claimActions.Add(new MultipleClaimAction(claimType, jsonKey));
}
public static void RemoveDuplicate(this ClaimActionCollection claimActions, string claimType)
{
claimActions.Add(new RemoveDuplicateClaimAction(claimType));
} }
} }

9
framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/AbpAspNetCoreAuthenticationOAuthModule.cs

@ -1,11 +1,10 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Security; using Volo.Abp.Security;
namespace Volo.Abp.AspNetCore.Authentication.OAuth namespace Volo.Abp.AspNetCore.Authentication.OAuth;
[DependsOn(typeof(AbpSecurityModule))]
public class AbpAspNetCoreAuthenticationOAuthModule : AbpModule
{ {
[DependsOn(typeof(AbpSecurityModule))]
public class AbpAspNetCoreAuthenticationOAuthModule : AbpModule
{
}
} }

71
framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs

@ -3,51 +3,50 @@ using System.Security.Claims;
using System.Text.Json; using System.Text.Json;
using Microsoft.AspNetCore.Authentication.OAuth.Claims; using Microsoft.AspNetCore.Authentication.OAuth.Claims;
namespace Volo.Abp.AspNetCore.Authentication.OAuth.Claims namespace Volo.Abp.AspNetCore.Authentication.OAuth.Claims;
public class MultipleClaimAction : ClaimAction
{ {
public class MultipleClaimAction : ClaimAction public MultipleClaimAction(string claimType, string jsonKey)
: base(claimType, jsonKey)
{ {
public MultipleClaimAction(string claimType, string jsonKey)
: base(claimType, jsonKey)
{
} }
public override void Run(JsonElement userData, ClaimsIdentity identity, string issuer) public override void Run(JsonElement userData, ClaimsIdentity identity, string issuer)
{ {
JsonElement prop; JsonElement prop;
if (!userData.TryGetProperty(ValueType, out prop)) if (!userData.TryGetProperty(ValueType, out prop))
return; return;
if (prop.ValueKind == JsonValueKind.Null)
{
return;
}
Claim claim; if (prop.ValueKind == JsonValueKind.Null)
switch (prop.ValueKind) {
{ return;
case JsonValueKind.String: }
claim = new Claim(ClaimType, prop.GetString(), ValueType, issuer);
Claim claim;
switch (prop.ValueKind)
{
case JsonValueKind.String:
claim = new Claim(ClaimType, prop.GetString(), ValueType, issuer);
if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value))
{
identity.AddClaim(claim);
}
break;
case JsonValueKind.Array:
foreach (var arramItem in prop.EnumerateArray())
{
claim = new Claim(ClaimType, arramItem.GetString(), ValueType, issuer);
if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value)) if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value))
{ {
identity.AddClaim(claim); identity.AddClaim(claim);
} }
break; }
case JsonValueKind.Array: break;
foreach (var arramItem in prop.EnumerateArray()) default:
{ throw new AbpException("Unhandled JsonValueKind: " + prop.ValueKind);
claim = new Claim(ClaimType, arramItem.GetString(), ValueType, issuer);
if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value))
{
identity.AddClaim(claim);
}
}
break;
default:
throw new AbpException("Unhandled JsonValueKind: " + prop.ValueKind);
}
} }
} }
} }

41
framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/RemoveDuplicateClaimAction.cs

@ -5,36 +5,35 @@ using System.Security.Claims;
using System.Text.Json; using System.Text.Json;
using Microsoft.AspNetCore.Authentication.OAuth.Claims; using Microsoft.AspNetCore.Authentication.OAuth.Claims;
namespace Volo.Abp.AspNetCore.Authentication.OAuth.Claims namespace Volo.Abp.AspNetCore.Authentication.OAuth.Claims;
public class RemoveDuplicateClaimAction : ClaimAction
{ {
public class RemoveDuplicateClaimAction : ClaimAction public RemoveDuplicateClaimAction(string claimType)
: base(claimType, ClaimValueTypes.String)
{ {
public RemoveDuplicateClaimAction(string claimType) }
: base(claimType, ClaimValueTypes.String)
/// <inheritdoc />
public override void Run(JsonElement userData, ClaimsIdentity identity, string issuer)
{
var claims = identity.Claims.Where(c => c.Type == ClaimType).ToArray();
if (claims.Length < 2)
{ {
return;
} }
/// <inheritdoc /> var previousValues = new List<string>();
public override void Run(JsonElement userData, ClaimsIdentity identity, string issuer) foreach (var claim in claims)
{ {
var claims = identity.Claims.Where(c => c.Type == ClaimType).ToArray(); if (claim.Value.IsIn(previousValues))
if (claims.Length < 2)
{ {
return; identity.RemoveClaim(claim);
} }
else
var previousValues = new List<string>();
foreach (var claim in claims)
{ {
if (claim.Value.IsIn(previousValues)) previousValues.Add(claim.Value);
{
identity.RemoveClaim(claim);
}
else
{
previousValues.Add(claim.Value);
}
} }
} }
} }
} }

81
framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Microsoft/Extensions/DependencyInjection/AbpOpenIdConnectExtensions.cs

@ -7,59 +7,58 @@ using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Volo.Abp.AspNetCore.MultiTenancy; using Volo.Abp.AspNetCore.MultiTenancy;
namespace Microsoft.Extensions.DependencyInjection namespace Microsoft.Extensions.DependencyInjection;
public static class AbpOpenIdConnectExtensions
{ {
public static class AbpOpenIdConnectExtensions public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder)
{ => builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, _ => { });
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder)
=> builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, _ => { });
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, Action<OpenIdConnectOptions> configureOptions) public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, Action<OpenIdConnectOptions> configureOptions)
=> builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, configureOptions); => builder.AddAbpOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, configureOptions);
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, Action<OpenIdConnectOptions> configureOptions) public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, Action<OpenIdConnectOptions> configureOptions)
=> builder.AddAbpOpenIdConnect(authenticationScheme, OpenIdConnectDefaults.DisplayName, configureOptions); => builder.AddAbpOpenIdConnect(authenticationScheme, OpenIdConnectDefaults.DisplayName, configureOptions);
public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<OpenIdConnectOptions> configureOptions) public static AuthenticationBuilder AddAbpOpenIdConnect(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<OpenIdConnectOptions> configureOptions)
{
return builder.AddOpenIdConnect(authenticationScheme, displayName, options =>
{ {
return builder.AddOpenIdConnect(authenticationScheme, displayName, options => options.ClaimActions.MapAbpClaimTypes();
{
options.ClaimActions.MapAbpClaimTypes();
configureOptions?.Invoke(options); configureOptions?.Invoke(options);
options.Events ??= new OpenIdConnectEvents(); options.Events ??= new OpenIdConnectEvents();
var authorizationCodeReceived = options.Events.OnAuthorizationCodeReceived ?? (_ => Task.CompletedTask); var authorizationCodeReceived = options.Events.OnAuthorizationCodeReceived ?? (_ => Task.CompletedTask);
options.Events.OnAuthorizationCodeReceived = receivedContext => options.Events.OnAuthorizationCodeReceived = receivedContext =>
{ {
SetAbpTenantId(receivedContext); SetAbpTenantId(receivedContext);
return authorizationCodeReceived.Invoke(receivedContext); return authorizationCodeReceived.Invoke(receivedContext);
}; };
options.Events.OnRemoteFailure = remoteFailureContext => options.Events.OnRemoteFailure = remoteFailureContext =>
{
if (remoteFailureContext.Failure is OpenIdConnectProtocolException &&
remoteFailureContext.Failure.Message.Contains("access_denied"))
{ {
if (remoteFailureContext.Failure is OpenIdConnectProtocolException && remoteFailureContext.HandleResponse();
remoteFailureContext.Failure.Message.Contains("access_denied")) remoteFailureContext.Response.Redirect($"{remoteFailureContext.Request.PathBase}/");
{ }
remoteFailureContext.HandleResponse(); return Task.CompletedTask;
remoteFailureContext.Response.Redirect($"{remoteFailureContext.Request.PathBase}/"); };
} });
return Task.CompletedTask; }
};
});
}
private static void SetAbpTenantId(AuthorizationCodeReceivedContext receivedContext) private static void SetAbpTenantId(AuthorizationCodeReceivedContext receivedContext)
{ {
var tenantKey = receivedContext.HttpContext.RequestServices var tenantKey = receivedContext.HttpContext.RequestServices
.GetRequiredService<IOptions<AbpAspNetCoreMultiTenancyOptions>>().Value.TenantKey; .GetRequiredService<IOptions<AbpAspNetCoreMultiTenancyOptions>>().Value.TenantKey;
if (receivedContext.Request.Cookies.ContainsKey(tenantKey)) if (receivedContext.Request.Cookies.ContainsKey(tenantKey))
{ {
receivedContext.TokenEndpointRequest.SetParameter(tenantKey, receivedContext.TokenEndpointRequest.SetParameter(tenantKey,
receivedContext.Request.Cookies[tenantKey]); receivedContext.Request.Cookies[tenantKey]);
}
} }
} }
} }

13
framework/src/Volo.Abp.AspNetCore.Authentication.OpenIdConnect/Volo/Abp/AspNetCore/Authentication/OpenIdConnect/AbpAspNetCoreAuthenticationOpenIdConnectModule.cs

@ -2,13 +2,12 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.Authentication.OpenIdConnect namespace Volo.Abp.AspNetCore.Authentication.OpenIdConnect;
[DependsOn(
typeof(AbpMultiTenancyModule),
typeof(AbpAspNetCoreAuthenticationOAuthModule))]
public class AbpAspNetCoreAuthenticationOpenIdConnectModule : AbpModule
{ {
[DependsOn(
typeof(AbpMultiTenancyModule),
typeof(AbpAspNetCoreAuthenticationOAuthModule))]
public class AbpAspNetCoreAuthenticationOpenIdConnectModule : AbpModule
{
}
} }

53
framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/AbpAspNetCoreComponentsServerThemingModule.cs

@ -4,34 +4,33 @@ using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages; using Volo.Abp.AspNetCore.Mvc.UI.Packages;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Components.Server.Theming namespace Volo.Abp.AspNetCore.Components.Server.Theming;
[DependsOn(
typeof(AbpAspNetCoreComponentsServerModule),
typeof(AbpAspNetCoreMvcUiPackagesModule),
typeof(AbpAspNetCoreComponentsWebThemingModule),
typeof(AbpAspNetCoreMvcUiBundlingModule)
)]
public class AbpAspNetCoreComponentsServerThemingModule : AbpModule
{ {
[DependsOn( public override void ConfigureServices(ServiceConfigurationContext context)
typeof(AbpAspNetCoreComponentsServerModule),
typeof(AbpAspNetCoreMvcUiPackagesModule),
typeof(AbpAspNetCoreComponentsWebThemingModule),
typeof(AbpAspNetCoreMvcUiBundlingModule)
)]
public class AbpAspNetCoreComponentsServerThemingModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) Configure<AbpBundlingOptions>(options =>
{ {
Configure<AbpBundlingOptions>(options => options
{ .StyleBundles
options .Add(BlazorStandardBundles.Styles.Global, bundle =>
.StyleBundles {
.Add(BlazorStandardBundles.Styles.Global, bundle => bundle.AddContributors(typeof(BlazorGlobalStyleContributor));
{ });
bundle.AddContributors(typeof(BlazorGlobalStyleContributor));
}); options
.ScriptBundles
options .Add(BlazorStandardBundles.Scripts.Global, bundle =>
.ScriptBundles {
.Add(BlazorStandardBundles.Scripts.Global, bundle => bundle.AddContributors(typeof(BlazorGlobalScriptContributor));
{ });
bundle.AddContributors(typeof(BlazorGlobalScriptContributor)); });
});
});
}
} }
} }

21
framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalBundles.cs

@ -1,15 +1,14 @@
namespace Volo.Abp.AspNetCore.Components.Server.Theming.Bundling namespace Volo.Abp.AspNetCore.Components.Server.Theming.Bundling;
public class BlazorStandardBundles
{ {
public class BlazorStandardBundles public static class Styles
{ {
public static class Styles public static string Global = "Blazor.Global";
{ }
public static string Global = "Blazor.Global";
}
public static class Scripts public static class Scripts
{ {
public static string Global = "Blazor.Global"; public static string Global = "Blazor.Global";
}
} }
} }

13
framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalScriptContributor.cs

@ -1,14 +1,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.Abp.AspNetCore.Components.Server.Theming.Bundling namespace Volo.Abp.AspNetCore.Components.Server.Theming.Bundling;
public class BlazorGlobalScriptContributor : BundleContributor
{ {
public class BlazorGlobalScriptContributor : BundleContributor public override void ConfigureBundle(BundleConfigurationContext context)
{ {
public override void ConfigureBundle(BundleConfigurationContext context) context.Files.AddIfNotContains("/_framework/blazor.server.js");
{ context.Files.AddIfNotContains("/_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js");
context.Files.AddIfNotContains("/_framework/blazor.server.js");
context.Files.AddIfNotContains("/_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js");
}
} }
} }

25
framework/src/Volo.Abp.AspNetCore.Components.Server.Theming/Bundling/BlazorGlobalStyleContributor.cs

@ -4,19 +4,18 @@ using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.FontAwesome; using Volo.Abp.AspNetCore.Mvc.UI.Packages.FontAwesome;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Components.Server.Theming.Bundling namespace Volo.Abp.AspNetCore.Components.Server.Theming.Bundling;
[DependsOn(
typeof(BootstrapStyleContributor),
typeof(FontAwesomeStyleContributor)
)]
public class BlazorGlobalStyleContributor : BundleContributor
{ {
[DependsOn( public override void ConfigureBundle(BundleConfigurationContext context)
typeof(BootstrapStyleContributor),
typeof(FontAwesomeStyleContributor)
)]
public class BlazorGlobalStyleContributor : BundleContributor
{ {
public override void ConfigureBundle(BundleConfigurationContext context) context.Files.AddIfNotContains("/_content/Blazorise/blazorise.css");
{ context.Files.AddIfNotContains("/_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css");
context.Files.AddIfNotContains("/_content/Blazorise/blazorise.css"); context.Files.AddIfNotContains("/_content/Blazorise.Snackbar/blazorise.snackbar.css");
context.Files.AddIfNotContains("/_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css");
context.Files.AddIfNotContains("/_content/Blazorise.Snackbar/blazorise.snackbar.css");
}
} }
} }

76
framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/AbpAspNetCoreComponentsServerModule.cs

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.Components.Web; using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
@ -12,49 +13,54 @@ using Volo.Abp.EventBus;
using Volo.Abp.Http.Client; using Volo.Abp.Http.Client;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Components.Server namespace Volo.Abp.AspNetCore.Components.Server;
[DependsOn(
typeof(AbpHttpClientModule),
typeof(AbpAspNetCoreComponentsWebModule),
typeof(AbpAspNetCoreSignalRModule),
typeof(AbpEventBusModule),
typeof(AbpAspNetCoreMvcContractsModule)
)]
public class AbpAspNetCoreComponentsServerModule : AbpModule
{ {
[DependsOn( public override void ConfigureServices(ServiceConfigurationContext context)
typeof(AbpHttpClientModule),
typeof(AbpAspNetCoreComponentsWebModule),
typeof(AbpAspNetCoreSignalRModule),
typeof(AbpEventBusModule),
typeof(AbpAspNetCoreMvcContractsModule)
)]
public class AbpAspNetCoreComponentsServerModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) var serverSideBlazorBuilder = context.Services.AddServerSideBlazor(options =>
{ {
var serverSideBlazorBuilder = context.Services.AddServerSideBlazor(); if (context.Services.GetHostingEnvironment().IsDevelopment())
context.Services.ExecutePreConfiguredActions(serverSideBlazorBuilder);
Configure<AbpAspNetCoreUnitOfWorkOptions>(options =>
{ {
options.IgnoredUrls.AddIfNotContains("/_blazor"); options.DetailedErrors = true;
}); }
});
context.Services.ExecutePreConfiguredActions(serverSideBlazorBuilder);
Configure<AbpAspNetCoreAuditingOptions>(options => Configure<AbpAspNetCoreUnitOfWorkOptions>(options =>
{ {
options.IgnoredUrls.AddIfNotContains("/_blazor"); options.IgnoredUrls.AddIfNotContains("/_blazor");
}); });
Configure<AbpEndpointRouterOptions>(options => Configure<AbpAspNetCoreAuditingOptions>(options =>
{
options.IgnoredUrls.AddIfNotContains("/_blazor");
});
Configure<AbpEndpointRouterOptions>(options =>
{
options.EndpointConfigureActions.Add(endpointContext =>
{ {
options.EndpointConfigureActions.Add(endpointContext => endpointContext.Endpoints.MapBlazorHub();
{ endpointContext.Endpoints.MapFallbackToPage("/_Host");
endpointContext.Endpoints.MapBlazorHub();
endpointContext.Endpoints.MapFallbackToPage("/_Host");
});
}); });
} });
}
public override void OnApplicationInitialization(ApplicationInitializationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context)
{ {
context.GetEnvironment().WebRootFileProvider = context.GetEnvironment().WebRootFileProvider =
new CompositeFileProvider( new CompositeFileProvider(
new ManifestEmbeddedFileProvider(typeof(IServerSideBlazorBuilder).Assembly), new ManifestEmbeddedFileProvider(typeof(IServerSideBlazorBuilder).Assembly),
context.GetEnvironment().WebRootFileProvider context.GetEnvironment().WebRootFileProvider
); );
}
} }
} }

37
framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Configuration/BlazorServerCurrentApplicationConfigurationCacheResetService.cs

@ -4,26 +4,25 @@ using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Local; using Volo.Abp.EventBus.Local;
namespace Volo.Abp.AspNetCore.Components.Server.Configuration namespace Volo.Abp.AspNetCore.Components.Server.Configuration;
[Dependency(ReplaceServices = true)]
public class BlazorServerCurrentApplicationConfigurationCacheResetService :
ICurrentApplicationConfigurationCacheResetService,
ITransientDependency
{ {
[Dependency(ReplaceServices = true)] private readonly ILocalEventBus _localEventBus;
public class BlazorServerCurrentApplicationConfigurationCacheResetService :
ICurrentApplicationConfigurationCacheResetService,
ITransientDependency
{
private readonly ILocalEventBus _localEventBus;
public BlazorServerCurrentApplicationConfigurationCacheResetService( public BlazorServerCurrentApplicationConfigurationCacheResetService(
ILocalEventBus localEventBus) ILocalEventBus localEventBus)
{ {
_localEventBus = localEventBus; _localEventBus = localEventBus;
} }
public async Task ResetAsync() public async Task ResetAsync()
{ {
await _localEventBus.PublishAsync( await _localEventBus.PublishAsync(
new CurrentApplicationConfigurationCacheResetEventData() new CurrentApplicationConfigurationCacheResetEventData()
); );
}
} }
} }

119
framework/src/Volo.Abp.AspNetCore.Components.Server/Volo/Abp/AspNetCore/Components/Server/Extensibility/BlazorServerLookupApiRequestService.cs

@ -13,78 +13,77 @@ using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.Authentication; using Volo.Abp.Http.Client.Authentication;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.Components.Server.Extensibility namespace Volo.Abp.AspNetCore.Components.Server.Extensibility;
public class BlazorServerLookupApiRequestService : ILookupApiRequestService, ITransientDependency
{ {
public class BlazorServerLookupApiRequestService : ILookupApiRequestService, ITransientDependency public IHttpClientFactory HttpClientFactory { get; }
public IRemoteServiceHttpClientAuthenticator HttpClientAuthenticator { get; }
public IRemoteServiceConfigurationProvider RemoteServiceConfigurationProvider { get; }
public ICurrentTenant CurrentTenant { get; }
public IHttpContextAccessor HttpContextAccessor { get; }
public NavigationManager NavigationManager { get; }
public BlazorServerLookupApiRequestService(IHttpClientFactory httpClientFactory,
IRemoteServiceHttpClientAuthenticator httpClientAuthenticator,
ICurrentTenant currentTenant,
IHttpContextAccessor httpContextAccessor,
NavigationManager navigationManager,
IRemoteServiceConfigurationProvider remoteServiceConfigurationProvider)
{ {
public IHttpClientFactory HttpClientFactory { get; } HttpClientFactory = httpClientFactory;
public IRemoteServiceHttpClientAuthenticator HttpClientAuthenticator { get; } HttpClientAuthenticator = httpClientAuthenticator;
public IRemoteServiceConfigurationProvider RemoteServiceConfigurationProvider { get; } CurrentTenant = currentTenant;
public ICurrentTenant CurrentTenant { get; } HttpContextAccessor = httpContextAccessor;
public IHttpContextAccessor HttpContextAccessor { get; } NavigationManager = navigationManager;
public NavigationManager NavigationManager { get; } RemoteServiceConfigurationProvider = remoteServiceConfigurationProvider;
}
public BlazorServerLookupApiRequestService(IHttpClientFactory httpClientFactory, public async Task<string> SendAsync(string url)
IRemoteServiceHttpClientAuthenticator httpClientAuthenticator, {
ICurrentTenant currentTenant, var client = HttpClientFactory.CreateClient();
IHttpContextAccessor httpContextAccessor, var requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
NavigationManager navigationManager,
IRemoteServiceConfigurationProvider remoteServiceConfigurationProvider)
{
HttpClientFactory = httpClientFactory;
HttpClientAuthenticator = httpClientAuthenticator;
CurrentTenant = currentTenant;
HttpContextAccessor = httpContextAccessor;
NavigationManager = navigationManager;
RemoteServiceConfigurationProvider = remoteServiceConfigurationProvider;
}
public async Task<string> SendAsync(string url) var uri = new Uri(url, UriKind.RelativeOrAbsolute);
if (!uri.IsAbsoluteUri)
{ {
var client = HttpClientFactory.CreateClient(); var baseUrl = string.Empty;
var requestMessage = new HttpRequestMessage(HttpMethod.Get, url); try
var uri = new Uri(url, UriKind.RelativeOrAbsolute);
if (!uri.IsAbsoluteUri)
{ {
var baseUrl = string.Empty; //Blazor tiered -- mode
try var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync("Default");
{ baseUrl = remoteServiceConfig.BaseUrl;
//Blazor tiered -- mode client.BaseAddress = new Uri(baseUrl);
var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync("Default"); AddHeaders(requestMessage);
baseUrl = remoteServiceConfig.BaseUrl; await HttpClientAuthenticator.Authenticate(new RemoteServiceHttpClientAuthenticateContext(client,
client.BaseAddress = new Uri(baseUrl); requestMessage, new RemoteServiceConfiguration(baseUrl), string.Empty));
AddHeaders(requestMessage); }
await HttpClientAuthenticator.Authenticate(new RemoteServiceHttpClientAuthenticateContext(client, catch (AbpException) // Blazor-Server mode.
requestMessage, new RemoteServiceConfiguration(baseUrl), string.Empty)); {
} baseUrl = NavigationManager.BaseUri;
catch (AbpException) // Blazor-Server mode. client.BaseAddress = new Uri(baseUrl);
foreach (var header in HttpContextAccessor.HttpContext.Request.Headers)
{ {
baseUrl = NavigationManager.BaseUri; requestMessage.Headers.Add(header.Key, header.Value.ToArray());
client.BaseAddress = new Uri(baseUrl);
foreach (var header in HttpContextAccessor.HttpContext.Request.Headers)
{
requestMessage.Headers.Add(header.Key, header.Value.ToArray());
}
} }
} }
var response = await client.SendAsync(requestMessage);
return await response.Content.ReadAsStringAsync();
} }
protected virtual void AddHeaders(HttpRequestMessage requestMessage) var response = await client.SendAsync(requestMessage);
return await response.Content.ReadAsStringAsync();
}
protected virtual void AddHeaders(HttpRequestMessage requestMessage)
{
if (CurrentTenant.Id.HasValue)
{ {
if (CurrentTenant.Id.HasValue) requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, CurrentTenant.Id.Value.ToString());
{ }
requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, CurrentTenant.Id.Value.ToString());
}
var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name; var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name;
if (!currentCulture.IsNullOrEmpty()) if (!currentCulture.IsNullOrEmpty())
{ {
requestMessage.Headers.AcceptLanguage.Add(new(currentCulture)); requestMessage.Headers.AcceptLanguage.Add(new(currentCulture));
}
} }
} }
} }

19
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/AbpAspNetCoreComponentsWebThemingModule.cs

@ -2,14 +2,13 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation; using Volo.Abp.UI.Navigation;
namespace Volo.Abp.AspNetCore.Components.Web.Theming namespace Volo.Abp.AspNetCore.Components.Web.Theming;
[DependsOn(
typeof(AbpBlazoriseUIModule),
typeof(AbpUiNavigationModule)
)]
public class AbpAspNetCoreComponentsWebThemingModule : AbpModule
{ {
[DependsOn(
typeof(AbpBlazoriseUIModule), }
typeof(AbpUiNavigationModule)
)]
public class AbpAspNetCoreComponentsWebThemingModule : AbpModule
{
}
}

95
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs

@ -5,69 +5,68 @@ using System.Threading.Tasks;
using Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars; using Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
using Volo.Abp.BlazoriseUI; using Volo.Abp.BlazoriseUI;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Layout namespace Volo.Abp.AspNetCore.Components.Web.Theming.Layout;
public partial class PageHeader : ComponentBase
{ {
public partial class PageHeader : ComponentBase protected List<RenderFragment> ToolbarItemRenders { get; set; }
{
protected List<RenderFragment> ToolbarItemRenders { get; set; }
public IPageToolbarManager PageToolbarManager { get; set; }
[Parameter]
public string Title { get; set; }
[Parameter] public IPageToolbarManager PageToolbarManager { get; set; }
public bool BreadcrumbShowHome { get; set; } = true;
[Parameter] [Parameter]
public bool BreadcrumbShowCurrent { get; set; } = true; public string Title { get; set; }
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public bool BreadcrumbShowHome { get; set; } = true;
[Parameter] [Parameter]
public List<BreadcrumbItem> BreadcrumbItems { get; set; } public bool BreadcrumbShowCurrent { get; set; } = true;
[Parameter]
public PageToolbar Toolbar { get; set; }
public PageHeader() [Parameter]
{ public RenderFragment ChildContent { get; set; }
BreadcrumbItems = new List<BreadcrumbItem>();
ToolbarItemRenders = new List<RenderFragment>(); [Parameter]
} public List<BreadcrumbItem> BreadcrumbItems { get; set; }
[Parameter]
public PageToolbar Toolbar { get; set; }
public PageHeader()
{
BreadcrumbItems = new List<BreadcrumbItem>();
ToolbarItemRenders = new List<RenderFragment>();
}
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{
await base.OnParametersSetAsync();
if (Toolbar != null)
{ {
await base.OnParametersSetAsync(); var toolbarItems = await PageToolbarManager.GetItemsAsync(Toolbar);
if (Toolbar!=null) ToolbarItemRenders.Clear();
{
var toolbarItems = await PageToolbarManager.GetItemsAsync(Toolbar);
ToolbarItemRenders.Clear();
foreach (var item in toolbarItems) foreach (var item in toolbarItems)
{
var sequence = 0;
ToolbarItemRenders.Add(builder =>
{ {
var sequence = 0; builder.OpenComponent(sequence, item.ComponentType);
ToolbarItemRenders.Add(builder => if (item.Arguments != null)
{ {
builder.OpenComponent(sequence, item.ComponentType); foreach (var argument in item.Arguments)
if (item.Arguments != null)
{ {
foreach (var argument in item.Arguments) sequence++;
{ builder.AddAttribute(sequence, argument.Key, argument.Value);
sequence++;
builder.AddAttribute(sequence, argument.Key, argument.Value);
}
} }
builder.CloseComponent(); }
}); builder.CloseComponent();
} });
} }
} }
}
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
await base.OnInitializedAsync(); await base.OnInitializedAsync();
}
} }
} }

9
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/IPageToolbarContributor.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public interface IPageToolbarContributor
{ {
public interface IPageToolbarContributor Task ContributeAsync(PageToolbarContributionContext context);
{
Task ContributeAsync(PageToolbarContributionContext context);
}
} }

9
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/IPageToolbarManager.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public interface IPageToolbarManager
{ {
public interface IPageToolbarManager Task<PageToolbarItem[]> GetItemsAsync(PageToolbar toolbar);
{
Task<PageToolbarItem[]> GetItemsAsync(PageToolbar toolbar);
}
} }

15
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbar.cs

@ -1,12 +1,11 @@
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbar
{ {
public class PageToolbar public PageToolbarContributorList Contributors { get; set; }
{
public PageToolbarContributorList Contributors { get; set; }
public PageToolbar() public PageToolbar()
{ {
Contributors = new PageToolbarContributorList(); Contributors = new PageToolbarContributorList();
}
} }
} }

25
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarContributionContext.cs

@ -1,21 +1,20 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using System; using System;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbarContributionContext
{ {
public class PageToolbarContributionContext [NotNull]
{ public IServiceProvider ServiceProvider { get; }
[NotNull]
public IServiceProvider ServiceProvider { get; }
[NotNull] [NotNull]
public PageToolbarItemList Items { get; } public PageToolbarItemList Items { get; }
public PageToolbarContributionContext( public PageToolbarContributionContext(
[NotNull] IServiceProvider serviceProvider) [NotNull] IServiceProvider serviceProvider)
{ {
ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider));
Items = new PageToolbarItemList(); Items = new PageToolbarItemList();
}
} }
} }

9
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarContributor.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public abstract class PageToolbarContributor : IPageToolbarContributor
{ {
public abstract class PageToolbarContributor : IPageToolbarContributor public abstract Task ContributeAsync(PageToolbarContributionContext context);
{
public abstract Task ContributeAsync(PageToolbarContributionContext context);
}
} }

7
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarContributorList.cs

@ -1,8 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbarContributorList : List<IPageToolbarContributor>
{ {
public class PageToolbarContributorList : List<IPageToolbarContributor>
{
}
} }

7
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarDictionary.cs

@ -1,9 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbarDictionary : Dictionary<string, PageToolbar>
{ {
public class PageToolbarDictionary : Dictionary<string, PageToolbar>
{
}
} }

97
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarExtensions.cs

@ -5,67 +5,66 @@ using System.Threading.Tasks;
using Volo.Abp.BlazoriseUI.Components; using Volo.Abp.BlazoriseUI.Components;
using Volo.Abp.Localization; using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public static class PageToolbarExtensions
{ {
public static class PageToolbarExtensions public static PageToolbar AddComponent<TComponent>(
this PageToolbar toolbar,
Dictionary<string, object> arguments = null,
int order = 0,
string requiredPolicyName = null)
{ {
public static PageToolbar AddComponent<TComponent>( return toolbar.AddComponent(
this PageToolbar toolbar, typeof(TComponent),
Dictionary<string, object> arguments = null, arguments,
int order = 0, order,
string requiredPolicyName = null) requiredPolicyName
{ );
return toolbar.AddComponent( }
typeof(TComponent),
public static PageToolbar AddComponent(
this PageToolbar toolbar,
Type componentType,
Dictionary<string, object> arguments = null,
int order = 0,
string requiredPolicyName = null)
{
toolbar.Contributors.Add(
new SimplePageToolbarContributor(
componentType,
arguments, arguments,
order, order,
requiredPolicyName requiredPolicyName
); )
} );
public static PageToolbar AddComponent(
this PageToolbar toolbar,
Type componentType,
Dictionary<string, object> arguments = null,
int order = 0,
string requiredPolicyName = null)
{
toolbar.Contributors.Add(
new SimplePageToolbarContributor(
componentType,
arguments,
order,
requiredPolicyName
)
);
return toolbar; return toolbar;
} }
public static PageToolbar AddButton( public static PageToolbar AddButton(
this PageToolbar toolbar, this PageToolbar toolbar,
string text, string text,
Func<Task> clicked, Func<Task> clicked,
object icon = null, object icon = null,
Color color = Color.Primary, Color color = Color.Primary,
bool disabled = false, bool disabled = false,
int order = 0, int order = 0,
string requiredPolicyName = null) string requiredPolicyName = null)
{ {
toolbar.AddComponent<ToolbarButton>( toolbar.AddComponent<ToolbarButton>(
new Dictionary<string, object> new Dictionary<string, object>
{ {
{ nameof(ToolbarButton.Color), color}, { nameof(ToolbarButton.Color), color},
{ nameof(ToolbarButton.Text), text}, { nameof(ToolbarButton.Text), text},
{ nameof(ToolbarButton.Disabled), disabled}, { nameof(ToolbarButton.Disabled), disabled},
{ nameof(ToolbarButton.Icon), icon}, { nameof(ToolbarButton.Icon), icon},
{ nameof(ToolbarButton.Clicked),clicked}, { nameof(ToolbarButton.Clicked),clicked},
}, },
order, order,
requiredPolicyName requiredPolicyName
); );
return toolbar; return toolbar;
}
} }
} }

33
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarItem.cs

@ -2,26 +2,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbarItem
{ {
public class PageToolbarItem [NotNull]
{ public Type ComponentType { get; }
[NotNull]
public Type ComponentType { get; }
[CanBeNull] [CanBeNull]
public Dictionary<string, object> Arguments { get; set; } public Dictionary<string, object> Arguments { get; set; }
public int Order { get; set; } public int Order { get; set; }
public PageToolbarItem( public PageToolbarItem(
[NotNull] Type componentType, [NotNull] Type componentType,
[CanBeNull] Dictionary<string, object> arguments = null, [CanBeNull] Dictionary<string, object> arguments = null,
int order = 0) int order = 0)
{ {
ComponentType = Check.NotNull(componentType, nameof(componentType)); ComponentType = Check.NotNull(componentType, nameof(componentType));
Arguments = arguments; Arguments = arguments;
Order = order; Order = order;
}
} }
} }

7
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarItemList.cs

@ -1,9 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbarItemList : List<PageToolbarItem>
{ {
public class PageToolbarItemList : List<PageToolbarItem>
{
}
} }

39
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/PageToolbarManager.cs

@ -5,36 +5,35 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class PageToolbarManager : IPageToolbarManager, ITransientDependency
{ {
public class PageToolbarManager : IPageToolbarManager, ITransientDependency protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
public PageToolbarManager(
IHybridServiceScopeFactory serviceScopeFactory)
{ {
protected IHybridServiceScopeFactory ServiceScopeFactory { get; } ServiceScopeFactory = serviceScopeFactory;
}
public PageToolbarManager( public virtual async Task<PageToolbarItem[]> GetItemsAsync(PageToolbar toolbar)
IHybridServiceScopeFactory serviceScopeFactory) {
if (toolbar == null || !toolbar.Contributors.Any())
{ {
ServiceScopeFactory = serviceScopeFactory; return Array.Empty<PageToolbarItem>();
} }
public virtual async Task<PageToolbarItem[]> GetItemsAsync(PageToolbar toolbar) using (var scope = ServiceScopeFactory.CreateScope())
{ {
if (toolbar == null || !toolbar.Contributors.Any()) var context = new PageToolbarContributionContext(scope.ServiceProvider);
{
return Array.Empty<PageToolbarItem>();
}
using (var scope = ServiceScopeFactory.CreateScope()) foreach (var contributor in toolbar.Contributors)
{ {
var context = new PageToolbarContributionContext(scope.ServiceProvider); await contributor.ContributeAsync(context);
foreach (var contributor in toolbar.Contributors)
{
await contributor.ContributeAsync(context);
}
return context.Items.OrderBy(i => i.Order).ToArray();
} }
return context.Items.OrderBy(i => i.Order).ToArray();
} }
} }
} }

63
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/PageToolbars/SimplePageToolbarContributor.cs

@ -4,50 +4,49 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.PageToolbars;
public class SimplePageToolbarContributor : IPageToolbarContributor
{ {
public class SimplePageToolbarContributor : IPageToolbarContributor public Type ComponentType { get; }
{
public Type ComponentType { get; }
public Dictionary<string, object> Arguments { get; set; } public Dictionary<string, object> Arguments { get; set; }
public int Order { get; } public int Order { get; }
public string RequiredPolicyName { get; } public string RequiredPolicyName { get; }
public SimplePageToolbarContributor( public SimplePageToolbarContributor(
Type componentType, Type componentType,
Dictionary<string, object> arguments = null, Dictionary<string, object> arguments = null,
int order = 0, int order = 0,
string requiredPolicyName = null) string requiredPolicyName = null)
{ {
ComponentType = componentType; ComponentType = componentType;
Arguments = arguments; Arguments = arguments;
Order = order; Order = order;
RequiredPolicyName = requiredPolicyName; RequiredPolicyName = requiredPolicyName;
} }
public async Task ContributeAsync(PageToolbarContributionContext context) public async Task ContributeAsync(PageToolbarContributionContext context)
{
if (await ShouldAddComponentAsync(context))
{ {
if (await ShouldAddComponentAsync(context)) context.Items.Add(new PageToolbarItem(ComponentType, Arguments, Order));
{
context.Items.Add(new PageToolbarItem(ComponentType, Arguments, Order));
}
} }
}
protected virtual async Task<bool> ShouldAddComponentAsync(PageToolbarContributionContext context) protected virtual async Task<bool> ShouldAddComponentAsync(PageToolbarContributionContext context)
{
if (RequiredPolicyName != null)
{ {
if (RequiredPolicyName != null) var authorizationService = context.ServiceProvider.GetRequiredService<IAuthorizationService>();
if (!await authorizationService.IsGrantedAsync(RequiredPolicyName))
{ {
var authorizationService = context.ServiceProvider.GetRequiredService<IAuthorizationService>(); return false;
if (!await authorizationService.IsGrantedAsync(RequiredPolicyName))
{
return false;
}
} }
return true;
} }
return true;
} }
} }

17
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Routing/AbpRouterOptions.cs

@ -1,16 +1,15 @@
using System.Reflection; using System.Reflection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Routing namespace Volo.Abp.AspNetCore.Components.Web.Theming.Routing;
public class AbpRouterOptions
{ {
public class AbpRouterOptions public Assembly AppAssembly { get; set; }
{
public Assembly AppAssembly { get; set; }
public RouterAssemblyList AdditionalAssemblies { get; } public RouterAssemblyList AdditionalAssemblies { get; }
public AbpRouterOptions() public AbpRouterOptions()
{ {
AdditionalAssemblies = new RouterAssemblyList(); AdditionalAssemblies = new RouterAssemblyList();
}
} }
} }

11
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Routing/RouterAssemblyList.cs

@ -1,10 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Routing namespace Volo.Abp.AspNetCore.Components.Web.Theming.Routing;
public class RouterAssemblyList : List<Assembly>
{ {
public class RouterAssemblyList : List<Assembly>
{ }
}
}

17
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/AbpToolbarOptions.cs

@ -1,16 +1,15 @@
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public class AbpToolbarOptions
{ {
public class AbpToolbarOptions [NotNull]
{ public List<IToolbarContributor> Contributors { get; }
[NotNull]
public List<IToolbarContributor> Contributors { get; }
public AbpToolbarOptions() public AbpToolbarOptions()
{ {
Contributors = new List<IToolbarContributor>(); Contributors = new List<IToolbarContributor>();
}
} }
} }

27
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarConfigurationContext.cs

@ -5,25 +5,24 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public interface IToolbarConfigurationContext : IServiceProviderAccessor
{ {
public interface IToolbarConfigurationContext : IServiceProviderAccessor Toolbar Toolbar { get; }
{
Toolbar Toolbar { get; }
IAuthorizationService AuthorizationService { get; } IAuthorizationService AuthorizationService { get; }
IStringLocalizerFactory StringLocalizerFactory { get; } IStringLocalizerFactory StringLocalizerFactory { get; }
Task<bool> IsGrantedAsync(string policyName); Task<bool> IsGrantedAsync(string policyName);
[CanBeNull] [CanBeNull]
IStringLocalizer GetDefaultLocalizer(); IStringLocalizer GetDefaultLocalizer();
[NotNull] [NotNull]
public IStringLocalizer GetLocalizer<T>(); public IStringLocalizer GetLocalizer<T>();
[NotNull] [NotNull]
public IStringLocalizer GetLocalizer(Type resourceType); public IStringLocalizer GetLocalizer(Type resourceType);
}
} }

11
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarContributor.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public interface IToolbarContributor
{ {
public interface IToolbarContributor Task ConfigureToolbarAsync(IToolbarConfigurationContext context);
{ }
Task ConfigureToolbarAsync(IToolbarConfigurationContext context);
}
}

9
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/IToolbarManager.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public interface IToolbarManager
{ {
public interface IToolbarManager Task<Toolbar> GetAsync(string name);
{
Task<Toolbar> GetAsync(string name);
}
} }

11
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/StandardToolbars.cs

@ -1,7 +1,6 @@
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public static class StandardToolbars
{ {
public static class StandardToolbars public const string Main = "Main";
{ }
public const string Main = "Main";
}
}

19
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/Toolbar.cs

@ -1,18 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public class Toolbar
{ {
public class Toolbar public string Name { get; }
{
public string Name { get; }
public List<ToolbarItem> Items { get; } public List<ToolbarItem> Items { get; }
public Toolbar([NotNull] string name) public Toolbar([NotNull] string name)
{ {
Name = Check.NotNull(name, nameof(name)); Name = Check.NotNull(name, nameof(name));
Items = new List<ToolbarItem>(); Items = new List<ToolbarItem>();
}
} }
} }

65
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarConfigurationContext.cs

@ -6,48 +6,47 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public class ToolbarConfigurationContext : IToolbarConfigurationContext
{ {
public class ToolbarConfigurationContext : IToolbarConfigurationContext public IServiceProvider ServiceProvider { get; }
{
public IServiceProvider ServiceProvider { get; }
private readonly IAbpLazyServiceProvider _lazyServiceProvider; private readonly IAbpLazyServiceProvider _lazyServiceProvider;
public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService<IAuthorizationService>(); public IAuthorizationService AuthorizationService => _lazyServiceProvider.LazyGetRequiredService<IAuthorizationService>();
public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>(); public IStringLocalizerFactory StringLocalizerFactory => _lazyServiceProvider.LazyGetRequiredService<IStringLocalizerFactory>();
public Toolbar Toolbar { get; } public Toolbar Toolbar { get; }
public ToolbarConfigurationContext(Toolbar toolbar, IServiceProvider serviceProvider) public ToolbarConfigurationContext(Toolbar toolbar, IServiceProvider serviceProvider)
{ {
Toolbar = toolbar; Toolbar = toolbar;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
_lazyServiceProvider = ServiceProvider.GetRequiredService<IAbpLazyServiceProvider>(); _lazyServiceProvider = ServiceProvider.GetRequiredService<IAbpLazyServiceProvider>();
} }
public Task<bool> IsGrantedAsync(string policyName) public Task<bool> IsGrantedAsync(string policyName)
{ {
return AuthorizationService.IsGrantedAsync(policyName); return AuthorizationService.IsGrantedAsync(policyName);
} }
[CanBeNull] [CanBeNull]
public IStringLocalizer GetDefaultLocalizer() public IStringLocalizer GetDefaultLocalizer()
{ {
return StringLocalizerFactory.CreateDefaultOrNull(); return StringLocalizerFactory.CreateDefaultOrNull();
} }
[NotNull] [NotNull]
public IStringLocalizer GetLocalizer<T>() public IStringLocalizer GetLocalizer<T>()
{ {
return StringLocalizerFactory.Create<T>(); return StringLocalizerFactory.Create<T>();
} }
[NotNull] [NotNull]
public IStringLocalizer GetLocalizer(Type resourceType) public IStringLocalizer GetLocalizer(Type resourceType)
{ {
return StringLocalizerFactory.Create(resourceType); return StringLocalizerFactory.Create(resourceType);
}
} }
} }

30
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarItem.cs

@ -1,23 +1,21 @@
using System; using System;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public class ToolbarItem
{ {
public class ToolbarItem public Type ComponentType {
{ get => _componentType;
public Type ComponentType set => _componentType = Check.NotNull(value, nameof(value));
{ }
get => _componentType; private Type _componentType;
set => _componentType = Check.NotNull(value, nameof(value));
}
private Type _componentType;
public int Order { get; set; } public int Order { get; set; }
public ToolbarItem([NotNull] Type componentType, int order = 0) public ToolbarItem([NotNull] Type componentType, int order = 0)
{ {
Order = order; Order = order;
ComponentType = Check.NotNull(componentType, nameof(componentType)); ComponentType = Check.NotNull(componentType, nameof(componentType));
}
} }
} }

43
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Toolbars/ToolbarManager.cs

@ -4,36 +4,35 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars namespace Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars;
public class ToolbarManager : IToolbarManager, ITransientDependency
{ {
public class ToolbarManager : IToolbarManager, ITransientDependency protected AbpToolbarOptions Options { get; }
protected IServiceProvider ServiceProvider { get; }
public ToolbarManager(
IOptions<AbpToolbarOptions> options,
IServiceProvider serviceProvider)
{ {
protected AbpToolbarOptions Options { get; } ServiceProvider = serviceProvider;
protected IServiceProvider ServiceProvider { get; } Options = options.Value;
}
public ToolbarManager( public async Task<Toolbar> GetAsync(string name)
IOptions<AbpToolbarOptions> options, {
IServiceProvider serviceProvider) var toolbar = new Toolbar(name);
{
ServiceProvider = serviceProvider;
Options = options.Value;
}
public async Task<Toolbar> GetAsync(string name) using (var scope = ServiceProvider.CreateScope())
{ {
var toolbar = new Toolbar(name); var context = new ToolbarConfigurationContext(toolbar, scope.ServiceProvider);
using (var scope = ServiceProvider.CreateScope()) foreach (var contributor in Options.Contributors)
{ {
var context = new ToolbarConfigurationContext(toolbar, scope.ServiceProvider); await contributor.ConfigureToolbarAsync(context);
foreach (var contributor in Options.Contributors)
{
await contributor.ConfigureToolbarAsync(context);
}
} }
return toolbar;
} }
return toolbar;
} }
} }

17
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpAspNetCoreApplicationCreationOptions.cs

@ -1,13 +1,12 @@
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
public class AbpAspNetCoreApplicationCreationOptions
{ {
public class AbpAspNetCoreApplicationCreationOptions public AbpApplicationCreationOptions ApplicationCreationOptions { get; }
{
public AbpApplicationCreationOptions ApplicationCreationOptions { get; }
public AbpAspNetCoreApplicationCreationOptions( public AbpAspNetCoreApplicationCreationOptions(
AbpApplicationCreationOptions applicationCreationOptions) AbpApplicationCreationOptions applicationCreationOptions)
{ {
ApplicationCreationOptions = applicationCreationOptions; ApplicationCreationOptions = applicationCreationOptions;
}
} }
} }

25
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpAspNetCoreComponentsWebModule.cs

@ -5,22 +5,21 @@ using Volo.Abp.AspNetCore.Components.DependencyInjection;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.UI; using Volo.Abp.UI;
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
[DependsOn(
typeof(AbpUiModule),
typeof(AbpAspNetCoreComponentsModule)
)]
public class AbpAspNetCoreComponentsWebModule : AbpModule
{ {
[DependsOn( public override void PreConfigureServices(ServiceConfigurationContext context)
typeof(AbpUiModule),
typeof(AbpAspNetCoreComponentsModule)
)]
public class AbpAspNetCoreComponentsWebModule : AbpModule
{ {
public override void PreConfigureServices(ServiceConfigurationContext context)
{
} }
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
context.Services.Replace(ServiceDescriptor.Transient<IComponentActivator, ServiceProviderComponentActivator>()); context.Services.Replace(ServiceDescriptor.Transient<IComponentActivator, ServiceProviderComponentActivator>());
}
} }
} }

123
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorClientHttpMessageHandler.cs

@ -9,90 +9,89 @@ using Microsoft.JSInterop;
using Volo.Abp.AspNetCore.Components.Progression; using Volo.Abp.AspNetCore.Components.Progression;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
public class AbpBlazorClientHttpMessageHandler : DelegatingHandler, ITransientDependency
{ {
public class AbpBlazorClientHttpMessageHandler : DelegatingHandler, ITransientDependency private readonly IJSRuntime _jsRuntime;
{
private readonly IJSRuntime _jsRuntime;
private readonly ICookieService _cookieService; private readonly ICookieService _cookieService;
private readonly NavigationManager _navigationManager; private readonly NavigationManager _navigationManager;
private readonly IUiPageProgressService _uiPageProgressService; private readonly IUiPageProgressService _uiPageProgressService;
private const string AntiForgeryCookieName = "XSRF-TOKEN"; private const string AntiForgeryCookieName = "XSRF-TOKEN";
private const string AntiForgeryHeaderName = "RequestVerificationToken"; private const string AntiForgeryHeaderName = "RequestVerificationToken";
public AbpBlazorClientHttpMessageHandler( public AbpBlazorClientHttpMessageHandler(
IJSRuntime jsRuntime, IJSRuntime jsRuntime,
ICookieService cookieService, ICookieService cookieService,
NavigationManager navigationManager, NavigationManager navigationManager,
IClientScopeServiceProviderAccessor clientScopeServiceProviderAccessor) IClientScopeServiceProviderAccessor clientScopeServiceProviderAccessor)
{ {
_jsRuntime = jsRuntime; _jsRuntime = jsRuntime;
_cookieService = cookieService; _cookieService = cookieService;
_navigationManager = navigationManager; _navigationManager = navigationManager;
_uiPageProgressService = clientScopeServiceProviderAccessor.ServiceProvider.GetRequiredService<IUiPageProgressService>(); _uiPageProgressService = clientScopeServiceProviderAccessor.ServiceProvider.GetRequiredService<IUiPageProgressService>();
} }
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{ {
try await _uiPageProgressService.Go(null, options =>
{ {
await _uiPageProgressService.Go(null, options => options.Type = UiPageProgressType.Info;
{ });
options.Type = UiPageProgressType.Info;
});
await SetLanguageAsync(request, cancellationToken); await SetLanguageAsync(request, cancellationToken);
await SetAntiForgeryTokenAsync(request); await SetAntiForgeryTokenAsync(request);
return await base.SendAsync(request, cancellationToken); return await base.SendAsync(request, cancellationToken);
}
finally
{
await _uiPageProgressService.Go(-1);
}
} }
finally
private async Task SetLanguageAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{ {
var selectedLanguage = await _jsRuntime.InvokeAsync<string>( await _uiPageProgressService.Go(-1);
"localStorage.getItem", }
cancellationToken, }
"Abp.SelectedLanguage"
);
if (!selectedLanguage.IsNullOrWhiteSpace()) private async Task SetLanguageAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{ {
request.Headers.AcceptLanguage.Clear(); var selectedLanguage = await _jsRuntime.InvokeAsync<string>(
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(selectedLanguage)); "localStorage.getItem",
} cancellationToken,
"Abp.SelectedLanguage"
);
if (!selectedLanguage.IsNullOrWhiteSpace())
{
request.Headers.AcceptLanguage.Clear();
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(selectedLanguage));
} }
}
private async Task SetAntiForgeryTokenAsync(HttpRequestMessage request) private async Task SetAntiForgeryTokenAsync(HttpRequestMessage request)
{
if (request.Method == HttpMethod.Get || request.Method == HttpMethod.Head ||
request.Method == HttpMethod.Trace || request.Method == HttpMethod.Options)
{ {
if (request.Method == HttpMethod.Get || request.Method == HttpMethod.Head || return;
request.Method == HttpMethod.Trace || request.Method == HttpMethod.Options) }
{
return;
}
var selfUri = new Uri(_navigationManager.Uri); var selfUri = new Uri(_navigationManager.Uri);
if (request.RequestUri.Host != selfUri.Host || request.RequestUri.Port != selfUri.Port) if (request.RequestUri.Host != selfUri.Host || request.RequestUri.Port != selfUri.Port)
{ {
return; return;
} }
var token = await _cookieService.GetAsync(AntiForgeryCookieName); var token = await _cookieService.GetAsync(AntiForgeryCookieName);
if (!token.IsNullOrWhiteSpace()) if (!token.IsNullOrWhiteSpace())
{ {
request.Headers.Add(AntiForgeryHeaderName, token); request.Headers.Add(AntiForgeryHeaderName, token);
}
} }
} }
} }

57
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpBlazorMessageLocalizerHelper.cs

@ -3,46 +3,45 @@ using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
public class AbpBlazorMessageLocalizerHelper<T>
{ {
public class AbpBlazorMessageLocalizerHelper<T> private readonly IStringLocalizer<T> stringLocalizer;
public AbpBlazorMessageLocalizerHelper(IStringLocalizer<T> stringLocalizer)
{ {
private readonly IStringLocalizer<T> stringLocalizer; this.stringLocalizer = stringLocalizer;
}
public AbpBlazorMessageLocalizerHelper(IStringLocalizer<T> stringLocalizer) public string Localize(string message, [CanBeNull] IEnumerable<string> arguments)
{
try
{ {
this.stringLocalizer = stringLocalizer; return arguments?.Count() > 0
? stringLocalizer[message, LocalizeMessageArguments(arguments)?.ToArray()]
: stringLocalizer[message];
} }
catch
public string Localize(string message, [CanBeNull] IEnumerable<string> arguments)
{ {
try return stringLocalizer[message];
{
return arguments?.Count() > 0
? stringLocalizer[message, LocalizeMessageArguments(arguments)?.ToArray()]
: stringLocalizer[message];
}
catch
{
return stringLocalizer[message];
}
} }
}
private IEnumerable<string> LocalizeMessageArguments(IEnumerable<string> arguments) private IEnumerable<string> LocalizeMessageArguments(IEnumerable<string> arguments)
{
foreach (var argument in arguments)
{ {
foreach (var argument in arguments) // first try to localize with "DisplayName:{Name}"
{ var localization = stringLocalizer[$"DisplayName:{argument}"];
// first try to localize with "DisplayName:{Name}"
var localization = stringLocalizer[$"DisplayName:{argument}"];
if (localization.ResourceNotFound) if (localization.ResourceNotFound)
{ {
// then try to localize with just "{Name}" // then try to localize with just "{Name}"
localization = stringLocalizer[argument]; localization = stringLocalizer[argument];
}
yield return localization;
} }
yield return localization;
} }
} }
} }

87
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/AbpUtilsService.cs

@ -2,50 +2,49 @@
using Microsoft.JSInterop; using Microsoft.JSInterop;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
public class AbpUtilsService : IAbpUtilsService, ITransientDependency
{ {
public class AbpUtilsService : IAbpUtilsService, ITransientDependency protected IJSRuntime JsRuntime { get; }
{
protected IJSRuntime JsRuntime { get; } public AbpUtilsService(IJSRuntime jsRuntime)
{
public AbpUtilsService(IJSRuntime jsRuntime) JsRuntime = jsRuntime;
{ }
JsRuntime = jsRuntime;
} public ValueTask AddClassToTagAsync(string tagName, string className)
{
public ValueTask AddClassToTagAsync(string tagName, string className) return JsRuntime.InvokeVoidAsync("abp.utils.addClassToTag", tagName, className);
{ }
return JsRuntime.InvokeVoidAsync("abp.utils.addClassToTag", tagName, className);
} public ValueTask RemoveClassFromTagAsync(string tagName, string className)
{
public ValueTask RemoveClassFromTagAsync(string tagName, string className) return JsRuntime.InvokeVoidAsync("abp.utils.removeClassFromTag", tagName, className);
{ }
return JsRuntime.InvokeVoidAsync("abp.utils.removeClassFromTag", tagName, className);
} public ValueTask<bool> HasClassOnTagAsync(string tagName, string className)
{
public ValueTask<bool> HasClassOnTagAsync(string tagName, string className) return JsRuntime.InvokeAsync<bool>("abp.utils.hasClassOnTag", tagName, className);
{ }
return JsRuntime.InvokeAsync<bool>("abp.utils.hasClassOnTag", tagName, className);
} public ValueTask ReplaceLinkHrefByIdAsync(string linkId, string hrefValue)
{
public ValueTask ReplaceLinkHrefByIdAsync(string linkId, string hrefValue) return JsRuntime.InvokeVoidAsync("abp.utils.replaceLinkHrefById", linkId, hrefValue);
{ }
return JsRuntime.InvokeVoidAsync("abp.utils.replaceLinkHrefById", linkId, hrefValue);
} public ValueTask ToggleFullscreenAsync()
{
public ValueTask ToggleFullscreenAsync() return JsRuntime.InvokeVoidAsync("abp.utils.toggleFullscreen");
{ }
return JsRuntime.InvokeVoidAsync("abp.utils.toggleFullscreen");
} public ValueTask RequestFullscreenAsync()
{
public ValueTask RequestFullscreenAsync() return JsRuntime.InvokeVoidAsync("abp.utils.requestFullscreen");
{ }
return JsRuntime.InvokeVoidAsync("abp.utils.requestFullscreen");
} public ValueTask ExitFullscreenAsync()
{
public ValueTask ExitFullscreenAsync() return JsRuntime.InvokeVoidAsync("abp.utils.exitFullscreen");
{
return JsRuntime.InvokeVoidAsync("abp.utils.exitFullscreen");
}
} }
} }

17
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Alerts/AlertManager.cs

@ -1,15 +1,14 @@
using Volo.Abp.AspNetCore.Components.Alerts; using Volo.Abp.AspNetCore.Components.Alerts;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Alerts namespace Volo.Abp.AspNetCore.Components.Web.Alerts;
public class AlertManager : IAlertManager, IScopedDependency
{ {
public class AlertManager : IAlertManager, IScopedDependency public AlertList Alerts { get; }
{
public AlertList Alerts { get; }
public AlertManager() public AlertManager()
{ {
Alerts = new AlertList(); Alerts = new AlertList();
}
} }
} }

11
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/ICurrentApplicationConfigurationCacheResetService.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Configuration namespace Volo.Abp.AspNetCore.Components.Web.Configuration;
public interface ICurrentApplicationConfigurationCacheResetService
{ {
public interface ICurrentApplicationConfigurationCacheResetService Task ResetAsync();
{ }
Task ResetAsync();
}
}

13
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Configuration/NullCurrentApplicationConfigurationCacheResetService.cs

@ -1,13 +1,12 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.Configuration namespace Volo.Abp.AspNetCore.Components.Web.Configuration;
public class NullCurrentApplicationConfigurationCacheResetService : ICurrentApplicationConfigurationCacheResetService, ISingletonDependency
{ {
public class NullCurrentApplicationConfigurationCacheResetService : ICurrentApplicationConfigurationCacheResetService, ISingletonDependency public Task ResetAsync()
{ {
public Task ResetAsync() return Task.CompletedTask;
{
return Task.CompletedTask;
}
} }
} }

15
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieOptions.cs

@ -1,11 +1,10 @@
using System; using System;
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
public class CookieOptions
{ {
public class CookieOptions public DateTimeOffset? ExpireDate { get; set; }
{ public string Path { get; set; }
public DateTimeOffset? ExpireDate { get; set; } public bool Secure { get; set; }
public string Path { get; set; } }
public bool Secure { get; set; }
}
}

43
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/CookieService.cs

@ -2,31 +2,30 @@
using Microsoft.JSInterop; using Microsoft.JSInterop;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
[Dependency(ReplaceServices = true)]
public class CookieService : ICookieService, ITransientDependency
{ {
[Dependency(ReplaceServices = true)] public IJSRuntime JsRuntime { get; }
public class CookieService : ICookieService, ITransientDependency
{
public IJSRuntime JsRuntime { get; }
public CookieService(IJSRuntime jsRuntime) public CookieService(IJSRuntime jsRuntime)
{ {
JsRuntime = jsRuntime; JsRuntime = jsRuntime;
} }
public async ValueTask SetAsync(string key, string value, CookieOptions options) public async ValueTask SetAsync(string key, string value, CookieOptions options)
{ {
await JsRuntime.InvokeVoidAsync("abp.utils.setCookieValue", key, value, options?.ExpireDate?.ToString("r"), options?.Path, options?.Secure); await JsRuntime.InvokeVoidAsync("abp.utils.setCookieValue", key, value, options?.ExpireDate?.ToString("r"), options?.Path, options?.Secure);
} }
public async ValueTask<string> GetAsync(string key) public async ValueTask<string> GetAsync(string key)
{ {
return await JsRuntime.InvokeAsync<string>("abp.utils.getCookieValue", key); return await JsRuntime.InvokeAsync<string>("abp.utils.getCookieValue", key);
} }
public async ValueTask DeleteAsync(string key, string path = null) public async ValueTask DeleteAsync(string key, string path = null)
{ {
await JsRuntime.InvokeVoidAsync("abp.utils.deleteCookie", key); await JsRuntime.InvokeVoidAsync("abp.utils.deleteCookie", key);
}
} }
} }

13
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DefaultServerUrlProvider.cs

@ -1,13 +1,12 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web namespace Volo.Abp.AspNetCore.Components.Web;
public class DefaultServerUrlProvider : IServerUrlProvider, ISingletonDependency
{ {
public class DefaultServerUrlProvider : IServerUrlProvider, ISingletonDependency public Task<string> GetBaseUrlAsync(string remoteServiceName = null)
{ {
public Task<string> GetBaseUrlAsync(string remoteServiceName = null) return Task.FromResult("/");
{
return Task.FromResult("/");
}
} }
} }

13
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/DependencyInjection/ComponentsClientScopeServiceProviderAccessor.cs

@ -1,12 +1,11 @@
using System; using System;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AspNetCore.Components.Web.DependencyInjection namespace Volo.Abp.AspNetCore.Components.Web.DependencyInjection;
public class ComponentsClientScopeServiceProviderAccessor :
IClientScopeServiceProviderAccessor,
ISingletonDependency
{ {
public class ComponentsClientScopeServiceProviderAccessor : public IServiceProvider ServiceProvider { get; set; }
IClientScopeServiceProviderAccessor,
ISingletonDependency
{
public IServiceProvider ServiceProvider { get; set; }
}
} }

87
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLogger.cs

@ -3,64 +3,63 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Components.ExceptionHandling; using Volo.Abp.AspNetCore.Components.ExceptionHandling;
namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling;
public class AbpExceptionHandlingLogger : ILogger
{ {
public class AbpExceptionHandlingLogger : ILogger private readonly IServiceCollection _serviceCollection;
private IUserExceptionInformer _userExceptionInformer;
public AbpExceptionHandlingLogger(IServiceCollection serviceCollection)
{ {
private readonly IServiceCollection _serviceCollection; _serviceCollection = serviceCollection;
private IUserExceptionInformer _userExceptionInformer; }
public AbpExceptionHandlingLogger(IServiceCollection serviceCollection) public virtual void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter)
{
if (exception == null)
{ {
_serviceCollection = serviceCollection; return;
} }
public virtual void Log<TState>( if (logLevel != LogLevel.Critical && logLevel != LogLevel.Error)
LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter)
{ {
if (exception == null) return;
{
return;
}
if (logLevel != LogLevel.Critical && logLevel != LogLevel.Error)
{
return;
}
TryInitialize();
if (_userExceptionInformer == null)
{
return;
}
_userExceptionInformer.Inform(new UserExceptionInformerContext(exception));
} }
protected virtual void TryInitialize() TryInitialize();
{
var serviceProvider = _serviceCollection.GetServiceProviderOrNull();
if (serviceProvider == null)
{
return;
}
_userExceptionInformer = serviceProvider.GetRequiredService<IUserExceptionInformer>();
}
public virtual bool IsEnabled(LogLevel logLevel) if (_userExceptionInformer == null)
{ {
return logLevel == LogLevel.Critical || logLevel == LogLevel.Error; return;
} }
public virtual IDisposable BeginScope<TState>(TState state) _userExceptionInformer.Inform(new UserExceptionInformerContext(exception));
}
protected virtual void TryInitialize()
{
var serviceProvider = _serviceCollection.GetServiceProviderOrNull();
if (serviceProvider == null)
{ {
return NullDisposable.Instance; return;
} }
_userExceptionInformer = serviceProvider.GetRequiredService<IUserExceptionInformer>();
}
public virtual bool IsEnabled(LogLevel logLevel)
{
return logLevel == LogLevel.Critical || logLevel == LogLevel.Error;
}
public virtual IDisposable BeginScope<TState>(TState state)
{
return NullDisposable.Instance;
} }
} }

43
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/AbpExceptionHandlingLoggerProvider.cs

@ -1,38 +1,37 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling;
public class AbpExceptionHandlingLoggerProvider : ILoggerProvider
{ {
public class AbpExceptionHandlingLoggerProvider : ILoggerProvider private AbpExceptionHandlingLogger _logger;
{ private static readonly object SyncObj = new object();
private AbpExceptionHandlingLogger _logger; private readonly IServiceCollection _serviceCollection;
private static readonly object SyncObj = new object();
private readonly IServiceCollection _serviceCollection;
public AbpExceptionHandlingLoggerProvider(IServiceCollection serviceCollection) public AbpExceptionHandlingLoggerProvider(IServiceCollection serviceCollection)
{ {
_serviceCollection = serviceCollection; _serviceCollection = serviceCollection;
} }
public ILogger CreateLogger(string categoryName) public ILogger CreateLogger(string categoryName)
{
if (_logger == null)
{ {
if (_logger == null) lock (SyncObj)
{ {
lock (SyncObj) if (_logger == null)
{ {
if (_logger == null) _logger = new AbpExceptionHandlingLogger(_serviceCollection);
{
_logger = new AbpExceptionHandlingLogger(_serviceCollection);
}
} }
} }
return _logger;
} }
public void Dispose() return _logger;
{ }
public void Dispose()
{
}
} }
} }

91
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/ExceptionHandling/UserExceptionInformer.cs

@ -9,65 +9,64 @@ using Volo.Abp.AspNetCore.ExceptionHandling;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Http; using Volo.Abp.Http;
namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling namespace Volo.Abp.AspNetCore.Components.Web.ExceptionHandling;
[Dependency(ReplaceServices = true)]
public class UserExceptionInformer : IUserExceptionInformer, IScopedDependency
{ {
[Dependency(ReplaceServices = true)] public ILogger<UserExceptionInformer> Logger { get; set; }
public class UserExceptionInformer : IUserExceptionInformer, IScopedDependency protected IUiMessageService MessageService { get; }
protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; }
protected AbpExceptionHandlingOptions Options { get; }
public UserExceptionInformer(
IUiMessageService messageService,
IExceptionToErrorInfoConverter exceptionToErrorInfoConverter,
IOptions<AbpExceptionHandlingOptions> options)
{
MessageService = messageService;
ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter;
Options = options.Value;
Logger = NullLogger<UserExceptionInformer>.Instance;
}
public void Inform(UserExceptionInformerContext context)
{ {
public ILogger<UserExceptionInformer> Logger { get; set; } //TODO: Create sync versions of the MessageService APIs.
protected IUiMessageService MessageService { get; }
protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; }
protected AbpExceptionHandlingOptions Options { get; } var errorInfo = GetErrorInfo(context);
public UserExceptionInformer( if (errorInfo.Details.IsNullOrEmpty())
IUiMessageService messageService,
IExceptionToErrorInfoConverter exceptionToErrorInfoConverter,
IOptions<AbpExceptionHandlingOptions> options)
{ {
MessageService = messageService; MessageService.Error(errorInfo.Message);
ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter;
Options = options.Value;
Logger = NullLogger<UserExceptionInformer>.Instance;
} }
else
public void Inform(UserExceptionInformerContext context)
{ {
//TODO: Create sync versions of the MessageService APIs. MessageService.Error(errorInfo.Details, errorInfo.Message);
}
}
var errorInfo = GetErrorInfo(context); public async Task InformAsync(UserExceptionInformerContext context)
{
var errorInfo = GetErrorInfo(context);
if (errorInfo.Details.IsNullOrEmpty()) if (errorInfo.Details.IsNullOrEmpty())
{ {
MessageService.Error(errorInfo.Message); await MessageService.Error(errorInfo.Message);
}
else
{
MessageService.Error(errorInfo.Details, errorInfo.Message);
}
} }
else
public async Task InformAsync(UserExceptionInformerContext context)
{ {
var errorInfo = GetErrorInfo(context); await MessageService.Error(errorInfo.Details, errorInfo.Message);
if (errorInfo.Details.IsNullOrEmpty())
{
await MessageService.Error(errorInfo.Message);
}
else
{
await MessageService.Error(errorInfo.Details, errorInfo.Message);
}
} }
}
protected virtual RemoteServiceErrorInfo GetErrorInfo(UserExceptionInformerContext context) protected virtual RemoteServiceErrorInfo GetErrorInfo(UserExceptionInformerContext context)
{
return ExceptionToErrorInfoConverter.Convert(context.Exception, options =>
{ {
return ExceptionToErrorInfoConverter.Convert(context.Exception, options => options.SendExceptionsDetailsToClients = Options.SendExceptionsDetailsToClients;
{ options.SendStackTraceToClients = Options.SendStackTraceToClients;
options.SendExceptionsDetailsToClients = Options.SendExceptionsDetailsToClients; });
options.SendStackTraceToClients = Options.SendStackTraceToClients;
});
}
} }
} }

25
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityAction.cs

@ -1,20 +1,19 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
public class EntityAction : IEquatable<EntityAction>
{ {
public class EntityAction : IEquatable<EntityAction> public string Text { get; set; }
public Func<object, Task> Clicked { get; set; }
public Func<object, string> ConfirmationMessage { get; set; }
public bool Primary { get; set; }
public object Color { get; set; }
public string Icon { get; set; }
public Func<object, bool> Visible { get; set; }
public bool Equals(EntityAction other)
{ {
public string Text { get; set; } return string.Equals(Text, other?.Text, StringComparison.OrdinalIgnoreCase);
public Func<object, Task> Clicked { get; set; }
public Func<object, string> ConfirmationMessage { get; set; }
public bool Primary { get; set; }
public object Color { get; set; }
public string Icon { get; set; }
public Func<object, bool> Visible { get; set; }
public bool Equals(EntityAction other)
{
return string.Equals(Text, other?.Text, StringComparison.OrdinalIgnoreCase);
}
} }
} }

13
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/EntityActions/EntityActionDictionary.cs

@ -1,12 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
public class EntityActionDictionary : Dictionary<string, List<EntityAction>>
{ {
public class EntityActionDictionary : Dictionary<string, List<EntityAction>> public List<EntityAction> Get<T>()
{ {
public List<EntityAction> Get<T>() return this.GetOrAdd(typeof(T).FullName, () => new List<EntityAction>());
{
return this.GetOrAdd(typeof(T).FullName, () => new List<EntityAction>());
}
} }
} }

11
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/ILookupApiRequestService.cs

@ -1,10 +1,9 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace Volo.Abp.AspNetCore.Components.Web.Extensibility namespace Volo.Abp.AspNetCore.Components.Web.Extensibility;
public interface ILookupApiRequestService
{ {
public interface ILookupApiRequestService Task<string> SendAsync([NotNull] string url);
{ }
Task<string> SendAsync([NotNull]string url);
}
}

37
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumn.cs

@ -4,25 +4,24 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions; using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns;
public class TableColumn
{ {
public class TableColumn public string Title { get; set; }
{ public string Data { get; set; }
public string Title { get; set; } [CanBeNull]
public string Data { get; set; } public string DisplayFormat { get; set; }
[CanBeNull] public IFormatProvider DisplayFormatProvider { get; set; } = CultureInfo.CurrentCulture;
public string DisplayFormat { get; set; } [CanBeNull]
public IFormatProvider DisplayFormatProvider { get; set; } = CultureInfo.CurrentCulture; public Type Component { get; set; }
[CanBeNull] public List<EntityAction> Actions { get; set; }
public Type Component { get; set; } [CanBeNull]
public List<EntityAction> Actions { get; set; } public Func<object, string> ValueConverter { get; set; }
[CanBeNull] public bool Sortable { get; set; }
public Func<object,string> ValueConverter { get; set; }
public bool Sortable { get; set; }
public TableColumn() public TableColumn()
{ {
Actions = new List<EntityAction>(); Actions = new List<EntityAction>();
}
} }
} }

13
framework/src/Volo.Abp.AspNetCore.Components.Web/Volo/Abp/AspNetCore/Components/Web/Extensibility/TableColumns/TableColumnDictionary.cs

@ -1,12 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns namespace Volo.Abp.AspNetCore.Components.Web.Extensibility.TableColumns;
public class TableColumnDictionary : Dictionary<string, List<TableColumn>>
{ {
public class TableColumnDictionary : Dictionary<string, List<TableColumn>> public List<TableColumn> Get<T>()
{ {
public List<TableColumn> Get<T>() return this.GetOrAdd(typeof(T).FullName, () => new List<TableColumn>());
{
return this.GetOrAdd(typeof(T).FullName, () => new List<TableColumn>());
}
} }
} }

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

Loading…
Cancel
Save