diff --git a/.gitignore b/.gitignore index 545de1cc28..1b1e3d8201 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ bld/ [Ll]og/ # Visual Studio 2015 cache/options directory -.vs/ +**/.vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ diff --git a/README.md b/README.md index f6304ad5b3..ee043bdb62 100644 --- a/README.md +++ b/README.md @@ -8,36 +8,25 @@ See the official [web site (abp.io)](https://abp.io/) for more information. ### Status -This project is in **very early preview** stage and it's not suggested to use it in a real project. +This project is in **preview** stage and it's not suggested to use it in production yet. ### Documentation See the documentation. -### How to Build - -- Run the `build-all.ps1`. It will build all the solutions in this repository. - ### Development #### Pre Requirements -- Visual Studio 2017 15.9.0+ +- Visual Studio 2019 16.1.0+ #### Framework -Framework solution is located under the `framework` folder. It has no external dependency. Just open `Volo.Abp.sln` by Visual Studio and start the development. +Framework solution is located under the `framework` folder. It has no external dependency. #### Modules/Templates -[Modules](modules/) and [Templates](templates/) have their own solutions and have **local references** to the framework. Unfortunately, Visual Studio has some problems with local references to projects those are out of the solution. As a workaround, you should follow the steps below in order to start developing a module/template: - -- Disable "*Automatically check for missing packages during build in Visual Studio*" in the Visual Studio options. - -![disable-package-restore-visual-studio](docs/en/images/disable-package-restore-visual-studio.png) - -- When you open a solution, first run `dotnet restore` in the root folder of the solution. -- When you change a dependency of a project (or any of the dependencies of your projects change their dependencies), run `dotnet restore` again. +[Modules](modules/) and [Templates](templates/) have their own solutions and have **local references** to the framework and each other. ### Contribution diff --git a/docs/cs/Index.md b/docs/cs/Index.md new file mode 100644 index 0000000000..3a86344660 --- /dev/null +++ b/docs/cs/Index.md @@ -0,0 +1,30 @@ +# ABP dokumentace + +ABP je **open source aplikační framework** se zaměřením na vývoj webových aplikací založených na ASP.NET Core, zároveň ho však lze využít i k vývoji jiných typů aplikací. + +K procházení dokumentace využijte navigační nabídky vlevo. + +## Stav projektu + +ABP je **novou generací** open source frameworku [ASP.NET Boilerplate](https://aspnetboilerplate.com/). V současné době je v ranné fázi a není připraven k ostrému nasazení. Na dokumentaci se stále pracuje a ještě zdaleka není dokončena. + +Pro aplikace na krátkodobé a ostré nasazení je doporučeno použít [ASP.NET Boilerplate](https://aspnetboilerplate.com/) framework, který je bohatý na funkce, vyspělý, aktivně udržovaný a aktuální. + +## Začínáme + +Nejsnazší cestou jak začít nový projekt s ABP je užití startovací šablony: + +* [ASP.NET Core MVC Šablona](Getting-Started-AspNetCore-MVC-Template.md) + +Pokud chcete začít od nuly (s prázdným projektem) tak manuálně nainstalujte ABP Framework s pomocí následujících tutoriálů: + +* [Konzolová Aplikace](Getting-Started-Console-Application.md) +* [ASP.NET Core Web Aplikace](Getting-Started-AspNetCore-Application.md) + +## Zdrojový kód + +ABP je hostovaný na GitHub. Zobrazit [zdrojový kód](https://github.com/abpframework/abp). + +## Chcete přispět? + +ABP je komunitně řízený open source projekt. Podívejte se na [průvodce pro přispěvatele](Contribution/Index.md) pokud chcete být součástí tohoto projektu. diff --git a/docs/cs/docs-nav.json b/docs/cs/docs-nav.json new file mode 100644 index 0000000000..4b976b4812 --- /dev/null +++ b/docs/cs/docs-nav.json @@ -0,0 +1,292 @@ +{ + "items": [ + { + "text": "Začínáme", + "items": [ + { + "text": "Ze startovacích šablon", + "items": [ + { + "text": "ASP.NET Core MVC", + "path": "Getting-Started-AspNetCore-MVC-Template.md" + } + ] + }, + { + "text": "Z prázdných projektů", + "items": [ + { + "text": "S ASP.NET Core Web aplikací", + "path": "Getting-Started-AspNetCore-Application.md" + }, + { + "text": "S konzolovou aplikací", + "path": "Getting-Started-Console-Application.md" + } + ] + } + ] + }, + { + "text": "Tutoriály", + "items": [ + { + "text": "Vývoj aplikace", + "items": [ + { + "text": "S ASP.NET Core MVC", + "path": "Tutorials/AspNetCore-Mvc/Part-I.md" + } + ] + } + ] + }, + { + "text": "CLI", + "path": "CLI.md" + }, + { + "text": "Základy", + "items": [ + { + "text": "Vkládání závislostí", + "path": "Dependency-Injection.md", + "items": [ + { + "text": "AutoFac integrace", + "path": "Autofac-Integration.md" + } + ] + }, + { + "text": "Virtuální systém souborů", + "path": "Virtual-File-System.md" + }, + { + "text": "Lokalizace", + "path": "Localization.md" + }, + { + "text": "Zpracování výjimek", + "path": "Exception-Handling.md" + }, + { + "text": "Validace" + }, + { + "text": "Autorizace" + }, + { + "text": "Ukládání do mezipaměti" + }, + { + "text": "Audit" + }, + { + "text": "Správa nastavení" + } + ] + }, + { + "text": "Události", + "items": [ + { + "text": "Event bus (místní)" + }, + { + "text": "Distribuovaný event bus", + "items": [ + { + "text": "RabbitMQ integrace" + } + ] + } + ] + }, + { + "text": "Služby", + "items": [ + { + "text": "Serializace objektu" + }, + { + "text": "Serializace JSON" + }, + { + "text": "Emailování" + }, + { + "text": "GUIDy" + }, + { + "text": "Vláknování" + }, + { + "text": "Časování" + } + ] + }, + { + "text": "Multitenance", + "path": "Multi-Tenancy.md" + }, + { + "text": "Vývoj modulů", + "items": [ + { + "text": "Základy", + "path": "Module-Development-Basics.md" + }, + { + "text": "Zásuvné moduly" + }, + { + "text": "Nejlepší praktiky", + "path": "Best-Practices/Index.md" + } + ] + }, + { + "text": "Domain driven design", + "path": "Domain-Driven-Design.md", + "items": [ + { + "text": "Doménová vrstva", + "items": [ + { + "text": "Entity & agregované kořeny", + "path": "Entities.md" + }, + { + "text": "Hodnotové objekty" + }, + { + "text": "Repozitáře", + "path": "Repositories.md" + }, + { + "text": "Doménové služby" + }, + { + "text": "Specifikace" + } + ] + }, + { + "text": "Aplikační vrstva", + "items": [ + { + "text": "Aplikační služby", + "path": "Application-Services.md" + }, + { + "text": "Objekty přenosu dat" + }, + { + "text": "Jednotka práce" + } + ] + } + ] + }, + { + "text": "ASP.NET Core", + "items": [ + { + "text": "API", + "items": [ + { + "text": "Automatické API řadiče", + "path": "AspNetCore/Auto-API-Controllers.md" + }, + { + "text": "Dynamičtí C# API klienti", + "path": "AspNetCore/Dynamic-CSharp-API-Clients.md" + } + ] + }, + { + "text": "Uživatelské rozhraní", + "items": [ + { + "text": "Správa klientských balíčků", + "path": "AspNetCore/Client-Side-Package-Management.md" + }, + { + "text": "Svazování & minifikace", + "path": "AspNetCore/Bundling-Minification.md" + }, + { + "text": "Tag pomocníci", + "path": "Tag-Helpers.md" + }, + { + "text": "Motivy", + "path": "AspNetCore/Theming.md" + } + ] + } + ] + }, + { + "text": "Přístup k datům", + "items": [ + { + "text": "Entity Framework Core integrace", + "path": "Entity-Framework-Core.md" + }, + { + "text": "MongoDB integrace", + "path": "MongoDB.md" + } + ] + }, + { + "text": "Pozadí", + "items": [ + { + "text": "Úkony na pozadí", + "path": "Background-Jobs.md", + "items": [ + { + "text": "Hangfire integrace", + "path": "Background-Jobs-Hangfire.md" + }, + { + "text": "RabbitMQ integrace", + "path": "Background-Jobs-RabbitMq.md" + } + ] + } + ] + }, + { + "text": "Vzorky", + "items": [ + { + "text": "Mikroslužby demo", + "path": "Samples/Microservice-Demo.md" + } + ] + }, + { + "text": "Moduly aplikace", + "path": "Modules/Index.md" + }, + { + "text": "Architektura mikroslužby", + "path": "Microservice-Architecture.md" + }, + { + "text": "Testování" + }, + { + "text": "Noční sestavení", + "path": "Nightly-Builds.md" + }, + { + "text": "Průvodce pro přispěvatele", + "path": "Contribution/Index.md" + } + ] +} \ No newline at end of file diff --git a/docs/docs-langs.json b/docs/docs-langs.json index 851c67d605..012c7e6ef0 100644 --- a/docs/docs-langs.json +++ b/docs/docs-langs.json @@ -1,5 +1,10 @@ { "Languages":[ + { + "DisplayName" : "Čeština", + "Code" : "cs", + "IsDefault": false + }, { "DisplayName" : "English", "Code" : "en", diff --git a/docs/en/AspNetCore/Auto-API-Controllers.md b/docs/en/AspNetCore/Auto-API-Controllers.md index d08f13003e..77819c48c9 100644 --- a/docs/en/AspNetCore/Auto-API-Controllers.md +++ b/docs/en/AspNetCore/Auto-API-Controllers.md @@ -2,7 +2,7 @@ Once you create an [application service](../Application-Services.md), you generally want to create an API controller to expose this service as an HTTP (REST) API endpoint. A typical API controller does nothing but redirects method calls to the application service and configures the REST API using attributes like [HttpGet], [HttpPost], [Route]... etc. -ABP can **automagically** configures your application services as MVC API Controllers by convention. Most of time you don't care about its detailed configuration, but it's possible fully customize it. +ABP can **automagically** configure your application services as API Controllers by convention. Most of time you don't care about its detailed configuration, but it's possible to fully customize it. ## Configuration diff --git a/docs/en/JavaScript/Dynamic-JavaScript-API-Clients.md b/docs/en/JavaScript/Dynamic-JavaScript-API-Clients.md new file mode 100644 index 0000000000..539d3ac15a --- /dev/null +++ b/docs/en/JavaScript/Dynamic-JavaScript-API-Clients.md @@ -0,0 +1,3 @@ +## Dynamic JavaScript API Clients + +TODO \ No newline at end of file diff --git a/docs/en/Startup-Templates/Mvc-Module.md b/docs/en/Startup-Templates/Mvc-Module.md index b641d78bac..96c91b4c4b 100644 --- a/docs/en/Startup-Templates/Mvc-Module.md +++ b/docs/en/Startup-Templates/Mvc-Module.md @@ -1,6 +1,160 @@ # MVC Module Startup Template -TODO +This template can be used to create a **reusable [application module](../Modules/Index.md)** based on the [module development best practices & conventions](../Best-Practices/Index.md). It is also suitable for creating **microservices** (with or without UI). +## How to Start With? +You can use the [ABP CLI](../CLI.md) to create a new project using this startup template. Alternatively, you can directly create & download from the [Get Started](https://abp.io/get-started) page. CLI approach is used here. +First, install the ABP CLI if you haven't installed before: + +```bash +dotnet tool install -g Volo.Abp.Cli +``` + +Then use the `abp new` command in an empty folder to create a new solution: + +```bash +abp new Acme.IssueManagement -t mvc-module +``` + +- `Acme.IssueManagement` is the solution name, like *YourCompany.YourProduct*. You can use single level, two-levels or three-levels naming. + +### Without User Interface + +The template comes with a UI by default. You can use `--no-ui` option to not include the UI layer. + +````bash +abp new Acme.IssueManagement -t mvc-module --no-ui +```` + +## Solution Structure + +Based on the options you've specified, you will get a slightly different solution structure. If you don't specify any option, you will have a solution like shown below: + +![issuemanagement-module-solution](../images/issuemanagement-module-solution.png) + +Projects are organized as `src`, `test` and `host` folders: + +* `src` folder contains the actual module which is layered based on [DDD](../Domain-Driven-Design.md) principles. +* `test` folder contains unit & integration tests. +* `host` folder contains applications with different configurations to demonstrate how to host the module in an application. These are not a part of the module, but useful on development. + +The diagram below shows the layers & project dependencies of the module: + +![layered-project-dependencies-module](../images/layered-project-dependencies-module.png) + +Each section below will explain the related project & its dependencies. + +### .Domain.Shared Project + +This project contains constants, enums and other objects these are actually a part of the domain layer, but needed to be used by all layers/projects in the solution. + +An `IssueType` enum and an `IssueConts` class (which may have some constant fields for the `Issue` entity, like `MaxTitleLength`) are good candidates for this project. + +- This project has no dependency to other projects in the solution. All other projects depend on this directly or indirectly. + +### .Domain Project + +This is the domain layer of the solution. It mainly contains [entities, aggregate roots](../Entities.md), [domain services](../Domain-Services.md), [value types](../Value-Types.md), [repository interfaces](../Repositories.md) and other domain objects. + +An `Issue` entity, an `IssueManager` domain service and an `IIssueRepository` interface are good candidates for this project. + +- Depends on the `.Domain.Shared` because it uses constants, enums and other objects defined in that project. + +### .Application.Contracts Project + +This project mainly contains [application service](../Application-Services.md) **interfaces** and [Data Transfer Objects](../Data-Transfer-Objects.md) (DTO) of the application layer. It does exists to separate interface & implementation of the application layer. In this way, the interface project can be shared to the clients as a contract package. + +An `IIssueAppService` interface and an `IssueCreationDto` class are good candidates for this project. + +- Depends on the `.Domain.Shared` because it may use constants, enums and other shared objects of this project in the application service interfaces and DTOs. + +### .Application Project + +This project contains the [application service](../Application-Services.md) **implementations** of the interfaces defined in the `.Application.Contracts` project. + +An `IssueAppService` class is a good candidate for this project. + +- Depends on the `.Application.Contracts` project to be able to implement the interfaces and use the DTOs. +- Depends on the `.Domain` project to be able to use domain objects (entities, repository interfaces... etc.) to perform the application logic. + +### .EntityFrameworkCore Project + +This is the integration project for EF Core. It defines the `DbContext` and implements repository interfaces defined in the `.Domain` project. + +- Depends on the `.Domain` project to be able to reference to entities and repository interfaces. + +> You can delete this project if you don't want to support EF Core for your module. + +### .MongoDB Project + +This is the integration project for MongoDB. + +- Depends on the `.Domain` project to be able to reference to entities and repository interfaces. + +> You can delete this project if you don't want to support MongoDB for your module. + +### Test Projects + +The solution has multiple test projects, one for each layer: + +- `.Domain.Tests` is used to test the domain layer. +- `.Application.Tests` is used to test the application layer. +- `.EntityFrameworkCore.Tests` is used to test EF Core configuration and custom repositories. +- `.MongoDB.Tests` is used to test EF Core configuration and custom repositories. +- `.TestBase` is a base (shared) project for all tests. + +In addition, `.HttpApi.Client.ConsoleTestApp` is a console application (not an automated test project) which demonstrate the usage of HTTP APIs from a Dotnet application. + +Test projects are prepared for integration testing; + +- It is fully integrated to ABP framework and all services in your application. +- It uses SQLite in-memory database for EF Core. For MongoDB, it uses the [Mongo2Go](https://github.com/Mongo2Go/Mongo2Go) library. +- Authorization is disabled, so any application service can be easily used in tests. + +You can still create unit tests for your classes which will be harder to write (because you will need to prepare mock/fake objects), but faster to run (because it only tests a single class and skips all initialization process). + +> Domain & Application tests are using EF Core. If you remove EF Core integration or you want to use MongoDB for testing these layers, you should manually change project references & module dependencies. + +### Host Projects + +The solution has a few host applications to run your module on development. Host applications are used to run your module in a fully configured application. It is useful on development. Host applications includes some other modules in addition to the module being developed: + +* + +Host applications support two types of scenarios. + +#### Single (Unified) Application Scenario + +If your module has a UI, then `.Web.Unified` application is used to host the UI and API on a single point. It has its own `appsettings.json` file (that includes the database connection string) and EF Core database migrations. + +For the `.Web.Unified` application, there is a single database, named `YourProjectName_Unified` (like *IssueManagement_Unified* for this sample). + +> If you've selected the `--no-ui` option, this project will not be in your solution. + +##### How to Run? + +Set it as the startup project, run `Update-Database` command for the EF Core from Package Manager Console and run your application. Default username is `admin` and password is `1q2w3E*`. + +#### Separated Deployment & Databases Scenario + +In this scenario, there are three applications; + +* `.IdentityServer` application is an authentication server used by other applications. It has its own `appsettings.json` that contains database connection and other configurations. +* `.HttpApi.Host` hosts the HTTP API of the module. It has its own `appsettings.json` that contains database connections and other configurations. +* `.Web.Host` host the UI of the module. This project contains an `appsettings.json` file, but it does not have a connection string because it never connects to the database. Instead, it mainly contains endpoint of the remote API server and the authentication server. + +The diagram below shows the relation of the applications: + +![tiered-solution-applications](../images/tiered-solution-applications.png) + +`.Web.Host` project uses OpenId Connect Authentication to get identity and access tokens for the current user from the `.IdentityServer`. Then uses the access token to call the `.HttpApi.Host`. HTTP API server uses bearer token authentication to obtain claims from the access token to authorize the current user. + +##### How to Run? + +You should run the application with the given order: + +- First, run the `.IdentityServer` since other applications depends on it. +- Then run the `.HttpApi.Host` since it is used by the `.Web.Host` application. +- Finally, you can run the `.Web.Host` project and login to the application using `admin` as the username and `1q2w3E*` as the password. \ No newline at end of file diff --git a/docs/en/Startup-Templates/Mvc.md b/docs/en/Startup-Templates/Mvc.md index 6916a630a3..cdaa689db2 100644 --- a/docs/en/Startup-Templates/Mvc.md +++ b/docs/en/Startup-Templates/Mvc.md @@ -61,7 +61,9 @@ If you don't specify any option, you will have a solution like shown below: ![bookstore-visual-studio-solution-v3](../images/bookstore-visual-studio-solution-v3.png) -Projects are organized in `src` and `test` folders. `src` folder contains the actual application which is layered based on [DDD](../Domain-Driven-Design.md) principles as mentioned before. The diagram below shows the layers & project dependencies of the solution: +Projects are organized in `src` and `test` folders. `src` folder contains the actual application which is layered based on [DDD](../Domain-Driven-Design.md) principles as mentioned before. + +The diagram below shows the layers & project dependencies of the application: ![layered-project-dependencies](../images/layered-project-dependencies.png) @@ -79,7 +81,7 @@ A `BookType` enum and a `BookConts` class (which may have some constant fields f This is the domain layer of the solution. It mainly contains [entities, aggregate roots](../Entities.md), [domain services](../Domain-Services.md), [value types](../Value-Types.md), [repository interfaces](../Repositories.md) and other domain objects. -A `Book` entity, a `BookManager` domain service and a `IBookRepository` interface are good candidates for this project. +A `Book` entity, a `BookManager` domain service and an `IBookRepository` interface are good candidates for this project. * Depends on the `.Domain.Shared` because it uses constants, enums and other objects defined in that project. @@ -87,12 +89,16 @@ A `Book` entity, a `BookManager` domain service and a `IBookRepository` interfac This project mainly contains [application service](../Application-Services.md) **interfaces** and [Data Transfer Objects](../Data-Transfer-Objects.md) (DTO) of the application layer. It does exists to separate interface & implementation of the application layer. In this way, the interface project can be shared to the clients as a contract package. +An `IBookAppService` interface and a `BookCreationDto` class are good candidates for this project. + * Depends on the `.Domain.Shared` because it may use constants, enums and other shared objects of this project in the application service interfaces and DTOs. #### .Application Project This project contains the [application service](../Application-Services.md) **implementations** of the interfaces defined in the `.Application.Contracts` project. +A `BookAppService` class is a good candidate for this project. + * Depends on the `.Application.Contracts` project to be able to implement the interfaces and use the DTOs. * Depends on the `.Domain` project to be able to use domain objects (entities, repository interfaces... etc.) to perform the application logic. @@ -181,7 +187,7 @@ The solution has multiple test projects, one for each layer: In addition, `.HttpApi.Client.ConsoleTestApp` is a console application (not an automated test project) which demonstrate the usage of HTTP APIs from a Dotnet application. -Test projects are prepared integration testing; +Test projects are prepared for integration testing; * It is fully integrated to ABP framework and all services in your application. * It uses SQLite in-memory database for EF Core. For MongoDB, it uses the [Mongo2Go](https://github.com/Mongo2Go/Mongo2Go) library. @@ -218,9 +224,9 @@ As different from the default structure, two new projects come into play: `.Iden #### .IdentityServer Project -This project is used as an authentication server for other projects. `.Web` project uses OpenId Connect Authentication to get identity and access tokens for the current user. Then uses the access token to call the HTTP API server. HTTP API server uses bearer token authentication to obtain claims from the access token to authorize the current user. +This project is used as an authentication server for other projects. `.Web` project uses OpenId Connect Authentication to get identity and access tokens for the current user from the IdentityServer. Then uses the access token to call the HTTP API server. HTTP API server uses bearer token authentication to obtain claims from the access token to authorize the current user. -![bookstore-visual-studio-solution-v3](../images/tiered-solution-applications.png) +![tiered-solution-applications](../images/tiered-solution-applications.png) ABP uses the open source [IdentityServer4](https://identityserver.io/) framework for the authentication between applications. See [IdentityServer4 documentation](http://docs.identityserver.io) for details about the IdentityServer4 and OpenID Connect protocol. @@ -228,9 +234,7 @@ It has its own `appsettings.json` that contains database connection and other co #### .HttpApi.Host Project -This project is an application that hosts the API of the solution. - -It has its own `appsettings.json` that contains database connection and other configurations. +This project is an application that hosts the API of the solution. It has its own `appsettings.json` that contains database connection and other configurations. #### .Web Project @@ -247,5 +251,10 @@ This project contains an `appsettings.json` file, but this time it does not have You should run the application with the given order: * First, run the `.IdentityServer` since other applications depends on it. -* Then run the `.HttpApi.Server` since it is used by the `.Web` application. -* Finally, you can run the `.Web` project and login to the application (using `admin` as the username and `1q2w3E*` as the password). \ No newline at end of file +* Then run the `.HttpApi.Host` since it is used by the `.Web` application. +* Finally, you can run the `.Web` project and login to the application (using `admin` as the username and `1q2w3E*` as the password). + +## What's Next? + +- See [Getting Started With the ASP.NET Core MVC Template](../Getting-Started-AspNetCore-MVC-Template.md) to create a new solution and run it for this template. +- See the [ASP.NET Core MVC Tutorial](../Tutorials/AspNetCore-Mvc/Part-I.md) to learn how to develop applications using this template. \ No newline at end of file diff --git a/docs/en/Value-Objects.md b/docs/en/Value-Objects.md new file mode 100644 index 0000000000..0c6c8d4424 --- /dev/null +++ b/docs/en/Value-Objects.md @@ -0,0 +1,3 @@ +## Value Objects + +TODO \ No newline at end of file diff --git a/docs/en/Value-Types.md b/docs/en/Value-Types.md deleted file mode 100644 index a0e340063c..0000000000 --- a/docs/en/Value-Types.md +++ /dev/null @@ -1,3 +0,0 @@ -## Value Types - -TODO \ No newline at end of file diff --git a/docs/en/images/disable-package-restore-visual-studio.png b/docs/en/images/disable-package-restore-visual-studio.png deleted file mode 100644 index 5d2343dc3f..0000000000 Binary files a/docs/en/images/disable-package-restore-visual-studio.png and /dev/null differ diff --git a/docs/en/images/issuemanagement-module-solution.png b/docs/en/images/issuemanagement-module-solution.png new file mode 100644 index 0000000000..181924dd90 Binary files /dev/null and b/docs/en/images/issuemanagement-module-solution.png differ diff --git a/docs/en/images/layered-project-dependencies-module.png b/docs/en/images/layered-project-dependencies-module.png new file mode 100644 index 0000000000..7592f49878 Binary files /dev/null and b/docs/en/images/layered-project-dependencies-module.png differ diff --git a/docs/zh-Hans/AspNetCore/Auto-API-Controllers.md b/docs/zh-Hans/AspNetCore/Auto-API-Controllers.md index f31b4d67cb..93ac124913 100644 --- a/docs/zh-Hans/AspNetCore/Auto-API-Controllers.md +++ b/docs/zh-Hans/AspNetCore/Auto-API-Controllers.md @@ -2,7 +2,7 @@ 创建[应用程序服务](Application-Services.md)后, 通常需要创建API控制器以将此服务公开为HTTP(REST)API端点. 典型的API控制器除了将方法调用重定向到应用程序服务并使用[HttpGet],[HttpPost],[Route]等属性配置REST API之外什么都不做. -ABP可以按照惯例 **自动** 将你的应用程序服务配置为MVC API控制器. 大多数时候你不关心它的详细配置,但它可以完全被自定义. +ABP可以按照惯例 **自动** 将你的应用程序服务配置为API控制器. 大多数时候你不关心它的详细配置,但它可以完全被自定义. ## 配置 diff --git a/docs/zh-Hans/Dynamic-JavaScript-API-Clients.md b/docs/zh-Hans/Dynamic-JavaScript-API-Clients.md new file mode 100644 index 0000000000..b7ca9a6965 --- /dev/null +++ b/docs/zh-Hans/Dynamic-JavaScript-API-Clients.md @@ -0,0 +1,3 @@ +## Dynamic JavaScript API Clients + + TODO \ No newline at end of file diff --git a/docs/zh-Hans/Value-Objects.md b/docs/zh-Hans/Value-Objects.md new file mode 100644 index 0000000000..6735074fd4 --- /dev/null +++ b/docs/zh-Hans/Value-Objects.md @@ -0,0 +1,3 @@ +## Value Objects + + TODO \ No newline at end of file diff --git a/docs/zh-Hans/Value-Types.md b/docs/zh-Hans/Value-Types.md deleted file mode 100644 index a0e340063c..0000000000 --- a/docs/zh-Hans/Value-Types.md +++ /dev/null @@ -1,3 +0,0 @@ -## Value Types - -TODO \ No newline at end of file diff --git a/docs/zh-Hans/images/disable-package-restore-visual-studio.png b/docs/zh-Hans/images/disable-package-restore-visual-studio.png deleted file mode 100644 index 5d2343dc3f..0000000000 Binary files a/docs/zh-Hans/images/disable-package-restore-visual-studio.png and /dev/null differ diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index be77f0ab24..42e4b28516 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.168 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28922.388 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}" EndProject @@ -238,6 +238,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.AspNetCore.Mvc.UI.Dashboards", "src\Volo.Abp.AspNetCore.Mvc.UI.Dashboards\Volo.Abp.AspNetCore.Mvc.UI.Dashboards.csproj", "{054D766D-5992-460E-A4D8-936D80BE2C1A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ldap", "src\Volo.Abp.Ldap\Volo.Abp.Ldap.csproj", "{4DADBBD2-4C63-4C90-9661-EBF6252A7D6F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Ldap.Tests", "test\Volo.Abp.Ldap.Tests\Volo.Abp.Ldap.Tests.csproj", "{38FB8F75-426E-4265-8D0E-E121837B6FCC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -708,6 +712,14 @@ Global {054D766D-5992-460E-A4D8-936D80BE2C1A}.Debug|Any CPU.Build.0 = Debug|Any CPU {054D766D-5992-460E-A4D8-936D80BE2C1A}.Release|Any CPU.ActiveCfg = Release|Any CPU {054D766D-5992-460E-A4D8-936D80BE2C1A}.Release|Any CPU.Build.0 = Release|Any CPU + {4DADBBD2-4C63-4C90-9661-EBF6252A7D6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4DADBBD2-4C63-4C90-9661-EBF6252A7D6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4DADBBD2-4C63-4C90-9661-EBF6252A7D6F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4DADBBD2-4C63-4C90-9661-EBF6252A7D6F}.Release|Any CPU.Build.0 = Release|Any CPU + {38FB8F75-426E-4265-8D0E-E121837B6FCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38FB8F75-426E-4265-8D0E-E121837B6FCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38FB8F75-426E-4265-8D0E-E121837B6FCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38FB8F75-426E-4265-8D0E-E121837B6FCC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -829,6 +841,8 @@ Global {F006B0B4-F25D-4511-9FB3-F17AA44BDCEA} = {447C8A77-E5F0-4538-8687-7383196D04EA} {EE1AAB08-3FBD-487F-B0B4-BEBA4B69528A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {054D766D-5992-460E-A4D8-936D80BE2C1A} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {4DADBBD2-4C63-4C90-9661-EBF6252A7D6F} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {38FB8F75-426E-4265-8D0E-E121837B6FCC} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pl.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pl.json new file mode 100644 index 0000000000..8509b7d02b --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/pl.json @@ -0,0 +1,11 @@ +{ + "culture": "pl", + "texts": { + "GivenTenantIsNotAvailable": "Podany tenant jest niedostępny: {0}", + "Tenant": "Tenant", + "Switch": "zmień", + "Name": "Nazwa", + "SwitchTenantHint": "Pozostaw pole nazwy puste, aby przełączyć się na stronę hosta.", + "NotSelected": "Nie wybrano" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/vi.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/vi.json new file mode 100644 index 0000000000..975e1b4590 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/vi.json @@ -0,0 +1,11 @@ +{ + "culture": "vi", + "texts": { + "GivenTenantIsNotAvailable": "Người thuê không có sẵn: {0}", + "Tenant": "Người thuê", + "Switch": "Chuyển đổi", + "Name": "Tên", + "SwitchTenantHint": "Để trống trường tên để chuyển sang phía máy chủ.", + "NotSelected": "Không được chọn" + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/FreezeUi/FreezeUiScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/FreezeUi/FreezeUiScriptContributor.cs new file mode 100644 index 0000000000..ffdd786250 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/FreezeUi/FreezeUiScriptContributor.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Core; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.FreezeUi +{ + [DependsOn(typeof(CoreScriptContributor))] + public class FreezeUiScriptContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/freeze-ui/freeze-ui.min.css"); + } + } +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/FreezeUi/FreezeUiStyleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/FreezeUi/FreezeUiStyleContributor.cs new file mode 100644 index 0000000000..96f4996663 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/FreezeUi/FreezeUiStyleContributor.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap; +using Volo.Abp.Modularity; + +namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.FreezeUi +{ + [DependsOn(typeof(BootstrapStyleContributor))] + public class FreezeUiStyleContributor : BundleContributor + { + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/libs/freeze-ui/freeze-ui.min.css"); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs index 10354b37d0..8271c0e05a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs @@ -3,6 +3,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Clipboard; using Volo.Abp.AspNetCore.Mvc.UI.Packages.DatatablesNetBs4; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.FreezeUi; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryForm; using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidationUnobtrusive; @@ -27,7 +28,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling typeof(DatatablesNetBs4ScriptContributor), typeof(SweetalertScriptContributor), typeof(ToastrScriptBundleContributor), - typeof(TimeagoScriptContributor))] + typeof(TimeagoScriptContributor), + typeof(FreezeUiScriptContributor))] public class SharedThemeGlobalScriptContributor : BundleContributor { public override void ConfigureBundle(BundleConfigurationContext context) @@ -40,7 +42,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling "/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/modal-manager.js", "/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js", "/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert/abp-sweetalert.js", - "/libs/abp/aspnetcore-mvc-ui-theme-shared/toastr/abp-toastr.js" + "/libs/abp/aspnetcore-mvc-ui-theme-shared/toastr/abp-toastr.js", + "/libs/abp/aspnetcore-mvc-ui-theme-shared/freeze-ui/abp-freeze-ui.js" }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalStyleContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalStyleContributor.cs index 3402b92e99..7fb8181373 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalStyleContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalStyleContributor.cs @@ -2,6 +2,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap; using Volo.Abp.AspNetCore.Mvc.UI.Packages.DatatablesNetBs4; using Volo.Abp.AspNetCore.Mvc.UI.Packages.FontAwesome; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.FreezeUi; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Select2; using Volo.Abp.AspNetCore.Mvc.UI.Packages.Toastr; using Volo.Abp.Modularity; @@ -13,7 +14,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Bundling typeof(FontAwesomeStyleContributor), typeof(ToastrStyleBundleContributor), typeof(Select2StyleContributor), - typeof(DatatablesNetBs4StyleContributor) + typeof(DatatablesNetBs4StyleContributor), + typeof(FreezeUiStyleContributor) )] public class SharedThemeGlobalStyleContributor : BundleContributor { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/freeze-ui/abp-freeze-ui.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/freeze-ui/abp-freeze-ui.js new file mode 100644 index 0000000000..309765a482 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/freeze-ui/abp-freeze-ui.js @@ -0,0 +1,46 @@ +var abp = abp || {}; +(function ($) { + if (!window.FreezeUI || !$) { + return; + } + + /* MESSAGE **************************************************/ + /*Package from https://alexradulescu.github.io/freeze-ui/*/ + + abp.ui = abp.ui || {}; + + /* UI BLOCK */ + + abp.ui.block = function (elm) { + if (elm) { + window.FreezeUI({ selector: elm }); + } else { + window.FreezeUI(); + } + }; + + abp.ui.unblock = function () { + window.UnFreezeUI(); + }; + + /* UI BUSY */ + + abp.ui.setBusy = function (element, text, freezeDelay) { + var opt = { text : text ? text : ' ' }; + + if (element) { + opt.element = element; + } + + if (freezeDelay) { + opt.freezeDelay = freezeDelay; + } + + window.FreezeUI(opt); + }; + + abp.ui.clearBusy = function () { + window.UnFreezeUI(); + }; + +})(jQuery); \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj index 47ed3724bd..9911b60b5c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj @@ -11,7 +11,7 @@ - + diff --git a/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj b/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj index 029669c348..2d003f1d48 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj +++ b/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj @@ -18,7 +18,7 @@ - + \ No newline at end of file diff --git a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs index 2e8c10bad0..0c31fa31ce 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs +++ b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs @@ -59,14 +59,14 @@ namespace Volo.Abp.AutoMapper //We should prevent duplicate mapping in an application, since Mapper is static. if (!_createdMappingsBefore) { + _createdMappingsBefore = true; + Mapper.Initialize(mapperConfigurationExpression => { ConfigureAll(new AbpAutoMapperConfigurationContext(mapperConfigurationExpression, scope.ServiceProvider)); }); ValidateAll(Mapper.Configuration); - - _createdMappingsBefore = true; } scope.ServiceProvider.GetRequiredService().Mapper = Mapper.Instance; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj index 708c296880..e181af68ac 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj +++ b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj @@ -17,7 +17,7 @@ - + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateInfo.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateInfo.cs index 4041dc8d7a..3809646ecc 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateInfo.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/TemplateInfo.cs @@ -6,10 +6,14 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building { public abstract class TemplateInfo { + [NotNull] public string Name { get; } public DatabaseProvider DefaultDatabaseProvider { get; } + [CanBeNull] + public string DocumentUrl { get; set; } + protected TemplateInfo( [NotNull] string name, DatabaseProvider defaultDatabaseProvider = DatabaseProvider.NotSpecified) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs index 64aa02ee6e..574dd32a3d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuilder.cs @@ -1,5 +1,7 @@ using System; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Volo.Abp.Cli.ProjectBuilding.Building; using Volo.Abp.DependencyInjection; @@ -7,6 +9,8 @@ namespace Volo.Abp.Cli.ProjectBuilding { public class ProjectBuilder : IProjectBuilder, ITransientDependency { + public ILogger Logger { get; set; } + protected ITemplateStore TemplateStore { get; } protected ITemplateInfoProvider TemplateInfoProvider { get; } @@ -14,6 +18,8 @@ namespace Volo.Abp.Cli.ProjectBuilding { TemplateStore = templateStore; TemplateInfoProvider = templateInfoProvider; + + Logger = NullLogger.Instance; } public async Task BuildAsync(ProjectBuildArgs args) @@ -44,6 +50,11 @@ namespace Volo.Abp.Cli.ProjectBuilding ProjectBuildPipelineBuilder.Build(context).Execute(context); + if (!templateInfo.DocumentUrl.IsNullOrEmpty()) + { + Logger.LogInformation("Check the documentation of this template: " + templateInfo.DocumentUrl); + } + return new ProjectBuildResult(context.Result.ZipContent, args.SolutionName.ProjectName); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Mvc/MvcTemplate.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Mvc/MvcTemplate.cs index 069c5fbf03..5df8167fad 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Mvc/MvcTemplate.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/Mvc/MvcTemplate.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.Mvc public MvcTemplate() : base(TemplateName, DatabaseProvider.EntityFrameworkCore) { - + DocumentUrl = "https://docs.abp.io/en/abp/latest/Startup-Templates/Mvc"; } public override IEnumerable GetCustomSteps(ProjectBuildContext context) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MvcModule/MvcModuleTemplate.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MvcModule/MvcModuleTemplate.cs index e3258ec8a6..e12f97a638 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MvcModule/MvcModuleTemplate.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MvcModule/MvcModuleTemplate.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Cli.ProjectBuilding.Templates.MvcModule public MvcModuleTemplate() : base(TemplateName) { - + DocumentUrl = "https://docs.abp.io/en/abp/latest/Startup-Templates/Mvc-Module"; } public override IEnumerable GetCustomSteps(ProjectBuildContext context) diff --git a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj index e5355a19c1..509a438e0f 100644 --- a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj +++ b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AsyncCrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AsyncCrudAppService.cs index 151212925a..7bc76d9923 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AsyncCrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AsyncCrudAppService.cs @@ -45,28 +45,46 @@ namespace Volo.Abp.Application.Services } public abstract class AsyncCrudAppService - : CrudAppServiceBase, - IAsyncCrudAppService + : AsyncCrudAppService + where TEntity : class, IEntity + where TEntityDto : IEntityDto + { + protected AsyncCrudAppService(IRepository repository) + : base(repository) + { + + } + + protected override TEntityDto MapToGetListOutputDto(TEntity entity) + { + return MapToGetOutputDto(entity); + } + } + + public abstract class AsyncCrudAppService + : CrudAppServiceBase, + IAsyncCrudAppService where TEntity : class, IEntity - where TEntityDto : IEntityDto + where TGetOutputDto : IEntityDto + where TGetListOutputDto : IEntityDto { public IAsyncQueryableExecuter AsyncQueryableExecuter { get; set; } protected AsyncCrudAppService(IRepository repository) - :base(repository) + : base(repository) { AsyncQueryableExecuter = DefaultAsyncQueryableExecuter.Instance; } - public virtual async Task GetAsync(TKey id) + public virtual async Task GetAsync(TKey id) { await CheckGetPolicyAsync(); var entity = await GetEntityByIdAsync(id); - return MapToEntityDto(entity); + return MapToGetOutputDto(entity); } - public virtual async Task> GetListAsync(TGetListInput input) + public virtual async Task> GetListAsync(TGetListInput input) { await CheckGetListPolicyAsync(); @@ -79,29 +97,29 @@ namespace Volo.Abp.Application.Services var entities = await AsyncQueryableExecuter.ToListAsync(query); - return new PagedResultDto( + return new PagedResultDto( totalCount, - entities.Select(MapToEntityDto).ToList() + entities.Select(MapToGetListOutputDto).ToList() ); } - public virtual async Task CreateAsync(TCreateInput input) + public virtual async Task CreateAsync(TCreateInput input) { await CheckCreatePolicyAsync(); var entity = MapToEntity(input); - - if(entity is IMultiTenant && !HasTenantIdProperty(entity)) + + if (entity is IMultiTenant && !HasTenantIdProperty(entity)) { TryToSetTenantId(entity); } - + await Repository.InsertAsync(entity, autoSave: true); - return MapToEntityDto(entity); + return MapToGetOutputDto(entity); } - public virtual async Task UpdateAsync(TKey id, TUpdateInput input) + public virtual async Task UpdateAsync(TKey id, TUpdateInput input) { await CheckUpdatePolicyAsync(); @@ -110,7 +128,7 @@ namespace Volo.Abp.Application.Services MapToEntity(input, entity); await Repository.UpdateAsync(entity, autoSave: true); - return MapToEntityDto(entity); + return MapToGetOutputDto(entity); } public virtual async Task DeleteAsync(TKey id) diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs index 2595bc6edd..1d43ff084d 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs @@ -44,8 +44,7 @@ namespace Volo.Abp.Application.Services } public abstract class CrudAppService - : CrudAppServiceBase, - ICrudAppService + : CrudAppService where TEntity : class, IEntity where TEntityDto : IEntityDto { @@ -55,15 +54,34 @@ namespace Volo.Abp.Application.Services } - public virtual TEntityDto Get(TKey id) + protected override TEntityDto MapToGetListOutputDto(TEntity entity) + { + return MapToGetOutputDto(entity); + } + } + + public abstract class CrudAppService + : CrudAppServiceBase, + ICrudAppService + where TEntity : class, IEntity + where TGetOutputDto : IEntityDto + where TGetListOutputDto : IEntityDto + { + protected CrudAppService(IRepository repository) + : base(repository) + { + + } + + public virtual TGetOutputDto Get(TKey id) { CheckGetPolicy(); var entity = GetEntityById(id); - return MapToEntityDto(entity); + return MapToGetOutputDto(entity); } - public virtual PagedResultDto GetList(TGetListInput input) + public virtual PagedResultDto GetList(TGetListInput input) { CheckGetListPolicy(); @@ -76,29 +94,29 @@ namespace Volo.Abp.Application.Services var entities = query.ToList(); - return new PagedResultDto( + return new PagedResultDto( totalCount, - entities.Select(MapToEntityDto).ToList() + entities.Select(MapToGetListOutputDto).ToList() ); } - public virtual TEntityDto Create(TCreateInput input) + public virtual TGetOutputDto Create(TCreateInput input) { CheckCreatePolicy(); var entity = MapToEntity(input); - - if(entity is IMultiTenant && !HasTenantIdProperty(entity)) + + if (entity is IMultiTenant && !HasTenantIdProperty(entity)) { TryToSetTenantId(entity); } - + Repository.Insert(entity, autoSave: true); - return MapToEntityDto(entity); + return MapToGetOutputDto(entity); } - public virtual TEntityDto Update(TKey id, TUpdateInput input) + public virtual TGetOutputDto Update(TKey id, TUpdateInput input) { CheckUpdatePolicy(); @@ -106,7 +124,7 @@ namespace Volo.Abp.Application.Services MapToEntity(input, entity); Repository.Update(entity, autoSave: true); - return MapToEntityDto(entity); + return MapToGetOutputDto(entity); } public virtual void Delete(TKey id) diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppServiceBase.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppServiceBase.cs index b678362c53..21c19a9a4a 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppServiceBase.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppServiceBase.cs @@ -13,10 +13,11 @@ namespace Volo.Abp.Application.Services /// This is a common base class for CrudAppService and AsyncCrudAppService classes. /// Inherit either from CrudAppService or AsyncCrudAppService, not from this class. /// - public abstract class CrudAppServiceBase : + public abstract class CrudAppServiceBase : ApplicationService where TEntity : class, IEntity - where TEntityDto : IEntityDto + where TGetOutputDto : IEntityDto + where TGetListOutputDto : IEntityDto { protected IRepository Repository { get; } @@ -100,19 +101,29 @@ namespace Volo.Abp.Application.Services } /// - /// Maps to . + /// Maps to . /// It uses by default. - /// It can be overrided for custom mapping. + /// It can be overriden for custom mapping. /// - protected virtual TEntityDto MapToEntityDto(TEntity entity) + protected virtual TGetOutputDto MapToGetOutputDto(TEntity entity) { - return ObjectMapper.Map(entity); + return ObjectMapper.Map(entity); } /// - /// Maps to to create a new entity. + /// Maps to . /// It uses by default. - /// It can be overrided for custom mapping. + /// It can be overriden for custom mapping. + /// + protected virtual TGetListOutputDto MapToGetListOutputDto(TEntity entity) + { + return ObjectMapper.Map(entity); + } + + /// + /// Maps to to create a new entity. + /// It uses by default. + /// It can be overriden for custom mapping. /// protected virtual TEntity MapToEntity(TCreateInput createInput) { @@ -140,7 +151,7 @@ namespace Volo.Abp.Application.Services /// /// Maps to to update the entity. /// It uses by default. - /// It can be overrided for custom mapping. + /// It can be overriden for custom mapping. /// protected virtual void MapToEntity(TUpdateInput updateInput, TEntity entity) { diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IAsyncCrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IAsyncCrudAppService.cs index 4f97c49ae0..8f07cb2412 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IAsyncCrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/IAsyncCrudAppService.cs @@ -25,16 +25,24 @@ namespace Volo.Abp.Application.Services } public interface IAsyncCrudAppService - : IApplicationService + : IAsyncCrudAppService where TEntityDto : IEntityDto { - Task GetAsync(TKey id); - Task> GetListAsync(TGetListInput input); + } + + public interface IAsyncCrudAppService + : IApplicationService + where TGetOutputDto : IEntityDto + where TGetListOutputDto : IEntityDto + { + Task GetAsync(TKey id); + + Task> GetListAsync(TGetListInput input); - Task CreateAsync(TCreateInput input); + Task CreateAsync(TCreateInput input); - Task UpdateAsync(TKey id, TUpdateInput input); + Task UpdateAsync(TKey id, TUpdateInput input); Task DeleteAsync(TKey id); } diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ICrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ICrudAppService.cs index 7e8b96b9f8..2f3b770849 100644 --- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ICrudAppService.cs +++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ICrudAppService.cs @@ -24,16 +24,24 @@ namespace Volo.Abp.Application.Services } public interface ICrudAppService - : IApplicationService + : ICrudAppService where TEntityDto : IEntityDto { - TEntityDto Get(TKey id); - PagedResultDto GetList(TGetListInput input); + } + + public interface ICrudAppService + : IApplicationService + where TGetOutputDto : IEntityDto + where TGetListOutputDto : IEntityDto + { + TGetOutputDto Get(TKey id); + + PagedResultDto GetList(TGetListInput input); - TEntityDto Create(TCreateInput input); + TGetOutputDto Create(TCreateInput input); - TEntityDto Update(TKey id, TUpdateInput input); + TGetOutputDto Update(TKey id, TUpdateInput input); void Delete(TKey id); } diff --git a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj index ccdccb5197..bc148b42c5 100644 --- a/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj +++ b/framework/src/Volo.Abp.EntityFrameworkCore.PostgreSql/Volo.Abp.EntityFrameworkCore.PostgreSql.csproj @@ -18,7 +18,7 @@ - + diff --git a/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj b/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj index fe8a6a4192..f92af19e56 100644 --- a/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj +++ b/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj b/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj index e4b9db1c7b..82a980f1cf 100644 --- a/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj +++ b/framework/src/Volo.Abp.HangFire/Volo.Abp.HangFire.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj index e608961fff..fa2bddfcc6 100644 --- a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj +++ b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj b/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj new file mode 100644 index 0000000000..6b1cba1094 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo.Abp.Ldap.csproj @@ -0,0 +1,24 @@ + + + + + + netstandard2.0 + Volo.Abp.Ldap + Volo.Abp.Ldap + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + + + + + diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs new file mode 100644 index 0000000000..22b9ca7a76 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/AbpLdapModule.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace Volo.Abp.Ldap +{ + [DependsOn( + typeof(AbpAutofacModule) + )] + public class AbpLdapModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + var configuration = context.Services.GetConfiguration(); + Configure(configuration.GetSection("LDAP")); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Exceptions/OrganizationNotExistException.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Exceptions/OrganizationNotExistException.cs new file mode 100644 index 0000000000..9d7fb220cc --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Exceptions/OrganizationNotExistException.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.Ldap.Exceptions +{ + public class OrganizationNotExistException : BusinessException + { + public OrganizationNotExistException(string distinguishedName) + : base("LDAP:000001", $"the organization distinguished named {distinguishedName} does not exist.") + { + + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/ILdapManager.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/ILdapManager.cs new file mode 100644 index 0000000000..f14e88b409 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/ILdapManager.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using Volo.Abp.Ldap.Modeling; + +namespace Volo.Abp.Ldap +{ + public interface ILdapManager + { + /// + /// query the specified organizations. + /// + /// filter: (&(name=xxx)(objectClass=organizationalUnit)) when name is not null + /// filter: (&(name=*)(objectClass=organizationalUnit)) when name is null + /// + /// + /// + /// + IList GetOrganizations(string name = null); + + /// + /// query the specified organization. + /// + /// filter: (&(distinguishedName=xxx)(objectClass=organizationalUnit)) when organizationName is not null + /// + /// + /// + /// + LdapOrganization GetOrganization(string distinguishedName); + + void AddSubOrganization(string organizationName, LdapOrganization parentOrganization); + void AddSubOrganization(string organizationName, string parentDistinguishedName); + + /// + /// query the specified users. + /// + /// filter: (&(name=xxx)(objectCategory=person)(objectClass=user)) when name is not null + /// filter: (&(name=*)(objectCategory=person)(objectClass=user)) when name is null + /// + /// filter: (&(displayName=xxx)(objectCategory=person)(objectClass=user)) when displayName is not null + /// filter: (&(displayName=*)(objectCategory=person)(objectClass=user)) when displayName is null + /// + /// filter: (&(cn=xxx)(objectCategory=person)(objectClass=user)) when commonName is not null + /// filter: (&(cn=*)(objectCategory=person)(objectClass=user)) when commonName is null + /// + /// + /// + /// + /// + /// + IList GetUsers(string name = null, string displayName = null, string commonName = null); + + /// + /// query the specified User. + /// + /// filter: (&(distinguishedName=xxx)(objectCategory=person)(objectClass=user)) when distinguishedName is not null + /// + /// + /// + /// + LdapUser GetUser(string distinguishedName); + + void AddUserToOrganization(string userName, string password, LdapOrganization parentOrganization); + void AddUserToOrganization(string userName, string password, string parentDistinguishedName); + + /// + /// Authenticate + /// + /// E.g administrator@yourdomain.com.cn + /// + /// + bool Authenticate(string userDomainName, string password); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapCredentials.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapCredentials.cs new file mode 100644 index 0000000000..a2d2eefd74 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapCredentials.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Ldap +{ + public class LdapCredentials + { + public string DomainUserName { get; set; } + + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapHelps.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapHelps.cs new file mode 100644 index 0000000000..49a60a964f --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapHelps.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; + +namespace Volo.Abp.Ldap +{ + public static class LdapHelps + { + public static string BuildCondition(string name, string value) + { + return string.IsNullOrWhiteSpace(value) ? "" : $"({name}={value})"; + } + + public static string BuildFilter(Dictionary conditions) + { + if (null == conditions ) + { + conditions = new Dictionary(); + } + + if (conditions.Keys.Count == 0) + { + conditions.Add("objectClass", "*"); // add default condition + } + + var subFilter = string.Empty; + foreach (var keyValuePair in conditions) + { + subFilter += BuildCondition(keyValuePair.Key, keyValuePair.Value); + } + + return $"(&{subFilter})"; + } + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapManager.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapManager.cs new file mode 100644 index 0000000000..615b22d70e --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapManager.cs @@ -0,0 +1,332 @@ +using System; +using Microsoft.Extensions.Options; +using Novell.Directory.Ldap; +using System.Collections.Generic; +using System.Text; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Ldap.Exceptions; +using Volo.Abp.Ldap.Modeling; + +namespace Volo.Abp.Ldap +{ + public class LdapManager : ILdapManager, ITransientDependency + { + private readonly string _searchBase; + private readonly LdapOptions _ldapOptions; + + private readonly string[] _attributes = + { + "objectCategory", "objectClass", "cn", "name", "distinguishedName", + "ou", + "sAMAccountName", "userPrincipalName", "telephoneNumber", "mail" + }; + + public LdapManager(IOptions ldapSettingsOptions) + { + _ldapOptions = ldapSettingsOptions.Value; + _searchBase = _ldapOptions.SearchBase; + } + + #region Organization + /// + /// query the specified organizations. + /// + /// filter: (&(name=xxx)(objectClass=organizationalUnit)) when name is not null + /// filter: (&(objectClass=organizationalUnit)) when name is null + /// + /// + /// + /// + public IList GetOrganizations(string name = null) + { + var conditions = new Dictionary + { + {"name", name}, + {"objectClass", "organizationalUnit"}, + }; + return Query(_searchBase, conditions); + } + + /// + /// query the specified organization. + /// + /// filter: (&(distinguishedName=xxx)(objectClass=organizationalUnit)) when organizationName is not null + /// + /// + /// + /// + public LdapOrganization GetOrganization(string distinguishedName) + { + distinguishedName = Check.NotNullOrWhiteSpace(distinguishedName, nameof(distinguishedName)); + var conditions = new Dictionary + { + {"distinguishedName", distinguishedName}, + {"objectClass", "organizationalUnit"}, + }; + return QueryOne(_searchBase, conditions); + } + + public void AddSubOrganization(string organizationName, LdapOrganization parentOrganization) + { + organizationName = Check.NotNullOrWhiteSpace(organizationName, nameof(organizationName)); + var dn = $"OU={organizationName},{parentOrganization.DistinguishedName}"; + + var attributeSet = new LdapAttributeSet + { + new LdapAttribute("objectCategory", $"CN=Organizational-Unit,CN=Schema,CN=Configuration,{_ldapOptions.DomainDistinguishedName}"), + new LdapAttribute("objectClass", new[] {"top", "organizationalUnit"}), + new LdapAttribute("name", organizationName), + }; + + var newEntry = new LdapEntry(dn, attributeSet); + + using (var ldapConnection = GetConnection()) + { + ldapConnection.Add(newEntry); + } + } + + public void AddSubOrganization(string organizationName, string parentDistinguishedName) + { + organizationName = Check.NotNullOrWhiteSpace(organizationName, nameof(organizationName)); + parentDistinguishedName = + Check.NotNullOrWhiteSpace(parentDistinguishedName, nameof(parentDistinguishedName)); + + var parentOrganization = GetOrganization(parentDistinguishedName); + if (null == parentOrganization) + { + throw new OrganizationNotExistException(parentDistinguishedName); + } + + AddSubOrganization(organizationName, parentOrganization); + } + + #endregion + + #region User + /// + /// query the specified users. + /// + /// filter: (&(name=xxx)(objectCategory=person)(objectClass=user)) when name is not null + /// filter: (&(objectCategory=person)(objectClass=user)) when name is null + /// + /// filter: (&(displayName=xxx)(objectCategory=person)(objectClass=user)) when displayName is not null + /// filter: (&(objectCategory=person)(objectClass=user)) when displayName is null + /// + /// filter: (&(cn=xxx)(objectCategory=person)(objectClass=user)) when commonName is not null + /// filter: (&(objectCategory=person)(objectClass=user)) when commonName is null + /// + /// + /// + /// + /// + /// + public IList GetUsers(string name = null, string displayName = null, string commonName = null) + { + var conditions = new Dictionary + { + {"objectCategory", "person"}, + {"objectClass", "user"}, + {"name", name}, + {"displayName", displayName}, + {"cn", commonName}, + }; + return Query(_searchBase, conditions); + } + + /// + /// query the specified User. + /// + /// filter: (&(distinguishedName=xxx)(objectCategory=person)(objectClass=user)) when distinguishedName is not null + /// + /// + /// + /// + public LdapUser GetUser(string distinguishedName) + { + distinguishedName = Check.NotNullOrWhiteSpace(distinguishedName, nameof(distinguishedName)); + var conditions = new Dictionary + { + {"objectCategory", "person"}, + {"objectClass", "user"}, + {"distinguishedName", distinguishedName}, + }; + return QueryOne(_searchBase, conditions); + } + + public void AddUserToOrganization(string userName, string password, LdapOrganization parentOrganization) + { + var dn = $"CN={userName},{parentOrganization.DistinguishedName}"; + var mail = $"{userName}@{_ldapOptions.DomainName}"; + sbyte[] encodedBytes = SupportClass.ToSByteArray(Encoding.Unicode.GetBytes($"\"{password}\"")); + + var attributeSet = new LdapAttributeSet + { + new LdapAttribute("instanceType", "4"), + new LdapAttribute("objectCategory", $"CN=Person,CN=Schema,CN=Configuration,{_ldapOptions.DomainDistinguishedName}"), + new LdapAttribute("objectClass", new[] {"top", "person", "organizationalPerson", "user"}), + new LdapAttribute("name", userName), + new LdapAttribute("cn", userName), + new LdapAttribute("sAMAccountName", userName), + new LdapAttribute("userPrincipalName", userName), + new LdapAttribute("sn", userName), + new LdapAttribute("displayName", userName), + new LdapAttribute("unicodePwd", encodedBytes), + new LdapAttribute("userAccountControl", "512"), + new LdapAttribute("mail", mail), + }; + var newEntry = new LdapEntry(dn, attributeSet); + + using (var ldapConnection = GetConnection()) + { + ldapConnection.Add(newEntry); + } + } + + public void AddUserToOrganization(string userName, string password, string parentDistinguishedName) + { + var dn = $"CN={userName},{parentDistinguishedName}"; + var mail = $"{userName}@{_ldapOptions.DomainName}"; + sbyte[] encodedBytes = SupportClass.ToSByteArray(Encoding.Unicode.GetBytes($"\"{password}\"")); + + var attributeSet = new LdapAttributeSet + { + new LdapAttribute("instanceType", "4"), + new LdapAttribute("objectCategory", $"CN=Person,CN=Schema,CN=Configuration,{_ldapOptions.DomainDistinguishedName}"), + new LdapAttribute("objectClass", new[] {"top", "person", "organizationalPerson", "user"}), + new LdapAttribute("name", userName), + new LdapAttribute("cn", userName), + new LdapAttribute("sAMAccountName", userName), + new LdapAttribute("userPrincipalName", userName), + new LdapAttribute("sn", userName), + new LdapAttribute("displayName", userName), + new LdapAttribute("unicodePwd", encodedBytes), + new LdapAttribute("userAccountControl", "512"), + new LdapAttribute("mail", mail), + }; + var newEntry = new LdapEntry(dn, attributeSet); + + using (var ldapConnection = GetConnection()) + { + ldapConnection.Add(newEntry); + } + } + + #endregion + + #region Authenticate + + /// + /// Authenticate + /// + /// E.g administrator@yourdomain.com.cn + /// + /// + public bool Authenticate(string userDomainName, string password) + { + try + { + using (GetConnection(userDomainName, password)) + { + return true; + } + } + catch (Exception ) + { + return false; + } + } + + #endregion + + private ILdapConnection GetConnection(string bindUserName = null, string bindUserPassword = null) + { + // bindUserName/bindUserPassword only be used when authenticate + bindUserName = bindUserName ?? _ldapOptions.Credentials.DomainUserName; + bindUserPassword = bindUserPassword ?? _ldapOptions.Credentials.Password; + + var ldapConnection = new LdapConnection() { SecureSocketLayer = _ldapOptions.UseSsl }; + if (_ldapOptions.UseSsl) + { + ldapConnection.UserDefinedServerCertValidationDelegate += (sender, certificate, chain, sslPolicyErrors) => true; + } + ldapConnection.Connect(_ldapOptions.ServerHost, _ldapOptions.ServerPort); + + if (_ldapOptions.UseSsl) + { + ldapConnection.Bind(LdapConnection.Ldap_V3, bindUserName, bindUserPassword); + } + else + { + ldapConnection.Bind(bindUserName, bindUserPassword); + } + return ldapConnection; + } + + private IList Query(string searchBase, Dictionary conditions) where T : class, ILdapEntry + { + var filter = LdapHelps.BuildFilter(conditions); + + var result = new List(); + + using (var ldapConnection = GetConnection()) + { + var search = ldapConnection.Search(searchBase, LdapConnection.SCOPE_SUB, filter, + _attributes, false, null, null); + + LdapMessage message; + while ((message = search.getResponse()) != null) + { + if (!(message is LdapSearchResult searchResultMessage)) + { + continue; + } + var entry = searchResultMessage.Entry; + if (typeof(T) == typeof(LdapOrganization)) + { + result.Add(new LdapOrganization(entry.getAttributeSet()) as T); + } + + if (typeof(T) == typeof(LdapUser)) + { + result.Add(new LdapUser(entry.getAttributeSet()) as T); + } + } + } + return result; + } + + private T QueryOne(string searchBase, Dictionary conditions) where T : class, ILdapEntry + { + var filter = LdapHelps.BuildFilter(conditions); + + using (var ldapConnection = GetConnection()) + { + var search = ldapConnection.Search(searchBase, LdapConnection.SCOPE_SUB, filter, + _attributes, false, null, null); + + LdapMessage message; + while ((message = search.getResponse()) != null) + { + if (!(message is LdapSearchResult searchResultMessage)) + { + continue; + } + var entry = searchResultMessage.Entry; + if (typeof(T) == typeof(LdapOrganization)) + { + return new LdapOrganization(entry.getAttributeSet()) as T; + } + + if (typeof(T) == typeof(LdapUser)) + { + return new LdapUser(entry.getAttributeSet()) as T; + } + return null; + } + } + return null; + } + + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapOptions.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapOptions.cs new file mode 100644 index 0000000000..7e4aacfa0e --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/LdapOptions.cs @@ -0,0 +1,24 @@ +namespace Volo.Abp.Ldap +{ + public class LdapOptions + { + public string ServerHost { get; set; } + + public int ServerPort { get; set; } + + public bool UseSsl { get; set; } + + public string SearchBase { get; set; } + + public string DomainName { get; set; } + + public string DomainDistinguishedName { get; set; } + + public LdapCredentials Credentials { get; set; } + + public LdapOptions() + { + Credentials = new LdapCredentials(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapEntry.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapEntry.cs new file mode 100644 index 0000000000..f15775fc06 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapEntry.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.Ldap.Modeling +{ + public interface ILdapEntry + { + string ObjectCategory { get; set; } + string[] ObjectClass { get; set; } + string Name { get; set; } + string DistinguishedName { get; set; } + string CommonName { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapOrganization.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapOrganization.cs new file mode 100644 index 0000000000..07c11000e8 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapOrganization.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.Ldap.Modeling +{ + public interface ILdapOrganization : ILdapEntry + { + string OrganizationUnit { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapUser.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapUser.cs new file mode 100644 index 0000000000..8ef68f6607 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/ILdapUser.cs @@ -0,0 +1,11 @@ +namespace Volo.Abp.Ldap.Modeling +{ + public interface ILdapUser : ILdapEntry + { + string SamAccountName { get; set; } + string UserPrincipalName { get; set; } + string DisplayName { get; set; } + string Email { get; set; } + string Phone { get; set; } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapEntryBase.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapEntryBase.cs new file mode 100644 index 0000000000..6658a983d0 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapEntryBase.cs @@ -0,0 +1,24 @@ +using Novell.Directory.Ldap; + +namespace Volo.Abp.Ldap.Modeling +{ + public abstract class LdapEntryBase : ILdapEntry + { + public string ObjectCategory { get; set; } + public string[] ObjectClass { get; set; } + public string Name { get; set; } + public string CommonName { get; set; } + public string DistinguishedName { get; set; } + + protected LdapEntryBase() { } + + protected LdapEntryBase(LdapAttributeSet attributeSet) + { + ObjectCategory = attributeSet.getAttribute("objectCategory")?.StringValue; + ObjectClass = attributeSet.getAttribute("objectClass")?.StringValueArray; + Name = attributeSet.getAttribute("name")?.StringValue; + CommonName = attributeSet.getAttribute("cn")?.StringValue; + DistinguishedName = attributeSet.getAttribute("distinguishedName")?.StringValue; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapOrganization.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapOrganization.cs new file mode 100644 index 0000000000..e401a2514d --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapOrganization.cs @@ -0,0 +1,17 @@ +using Novell.Directory.Ldap; + +namespace Volo.Abp.Ldap.Modeling +{ + public class LdapOrganization : LdapEntryBase, ILdapOrganization + { + public string OrganizationUnit { get; set; } + + public LdapOrganization() { } + + public LdapOrganization(LdapAttributeSet attributeSet) + : base(attributeSet) + { + OrganizationUnit = attributeSet.getAttribute("ou")?.StringValue; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapUser.cs b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapUser.cs new file mode 100644 index 0000000000..d9f554d512 --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/Volo/Abp/Ldap/Modeling/LdapUser.cs @@ -0,0 +1,25 @@ +using Novell.Directory.Ldap; + +namespace Volo.Abp.Ldap.Modeling +{ + public class LdapUser : LdapEntryBase, ILdapUser + { + public string SamAccountName { get; set; } + public string UserPrincipalName { get; set; } + public string DisplayName { get; set; } + public string Email { get; set; } + public string Phone { get; set; } + + public LdapUser() { } + + public LdapUser( LdapAttributeSet attributeSet) + : base(attributeSet) + { + SamAccountName = attributeSet.getAttribute("sAMAccountName")?.StringValue; + UserPrincipalName = attributeSet.getAttribute("userPrincipalName")?.StringValue; + DisplayName = attributeSet.getAttribute("displayName")?.StringValue; + Email = attributeSet.getAttribute("mail")?.StringValue; + Phone = attributeSet.getAttribute("telephoneNumber")?.StringValue; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap/readme.md b/framework/src/Volo.Abp.Ldap/readme.md new file mode 100644 index 0000000000..dd9b84087d --- /dev/null +++ b/framework/src/Volo.Abp.Ldap/readme.md @@ -0,0 +1,171 @@ +# Volo.Abp.Ldap + +# Only Authenticate(not read/write AD) + +## Configure + +add section in `appsettings.json` + +### use SSL + +```json +"LDAP": { + "ServerHost": "192.168.101.54", + "ServerPort": 636, + "UseSsl": true +} +``` + +### not use SSL + +```json +"LDAP": { + "ServerHost": "192.168.101.54", + "ServerPort": 389, + "UseSsl": false +} +``` + +## Authenticate + + Injecting `ILdapManager` into a class. For example: + +```csharp +public class TaxAppService : ApplicationService +{ + private readonly ILdapManager _ldapManager; + + public TaxAppService(ILdapManager ldapManager) + { + _ldapManager = ldapManager; + } + + public void Authenticate(string userName, string password) + { + var result = _ldapManager.Authenticate(userName, password); + } +} +``` + +- `userName` must be full domain name. E.g abc@abc.com + +# Read/Write AD + +## Configure + +### use SSL + +```json +"LDAP": { + "ServerHost": "192.168.101.54", + "ServerPort": 636, + "UseSsl": true, + "Credentials": { + "DomainUserName": "administrator@yourdomain.com.cn", + "Password": "yH.20190528" + }, + "SearchBase": "DC=yourdomain,DC=com,DC=cn", + "DomainName": "yourdomain.com.cn", + "DomainDistinguishedName": "DC=yourdomain,DC=com,DC=cn" +} +``` + +### not use SSL + +```json +"LDAP": { + "ServerHost": "192.168.101.54", + "ServerPort": 389, + "UseSsl": false, + "Credentials": { + "DomainUserName": "administrator@yourdomain.com.cn", + "Password": "yH.20190528" + }, + "SearchBase": "DC=yourdomain,DC=com,DC=cn", + "DomainName": "yourdomain.com.cn", + "DomainDistinguishedName": "DC=yourdomain,DC=com,DC=cn" +} +``` + +- `Credentials:DomainUserName` a administrator of AD. + +- `Credentials:Password` the password for the administrator. +- `SearchBase`: where search from AD. +- `DomainName`: name of you domain. no need `www`. +- `DomainDistinguishedName`: distinguished name of root domain. + +## Query Organizations + +```cs +// query all organizations +// filter: (&(objectClass=organizationalUnit)) +_ldapManager.GetOrganizations(); + +// query organizations by name +// filter: (&(name=abc)(objectClass=organizationalUnit)) +_ldapManager.GetOrganizations("abc"); + +``` + +## Query Organization + +```csharp +// query organization by distinguished name +// filter: (&(distinguishedName=abc)(objectClass=organizationalUnit)) +_ldapManager.GetOrganization("abc"); + +``` + +## Add Organization + +```csharp +// use LdapOrganization +_ldapManager.AddSubOrganization("nameA", parentOrganization); + +// or use OrganizationDistinguishedName +_ldapManager.AddSubOrganization("nameA", "OU=Domain Controllers,DC=yourdomain,DC=com,DC=cn"); +``` + +## Query Users + +```cs +// query all users +// filter: (&(objectCategory=person)(objectClass=user)) +_ldapManager.GetUsers(); + +// query organizations by name +// filter: (&(name=abc)(objectCategory=person)(objectClass=user)) +_ldapManager.GetUsers(name : "abc"); + +// query organizations by displayName +// filter: (&(displayName=abc)(objectCategory=person)(objectClass=user)) +_ldapManager.GetUsers(displayName : "abc"); + +// query organization by commonName +// filter: (&(cn=abc)(objectCategory=person)(objectClass=user)) +_ldapManager.GetUsers(commonName : "abc"); + +``` + +## Query User + +```csharp +// query a user by distinguished name +// filter: (&(distinguishedName=abc)(objectCategory=person)(objectClass=user)) +_ldapManager.GetUser("abc"); + +``` + +## Add User + +```csharp +// use LdapOrganization +_ldapManager.AddUserToOrganization("nameA", "passwordA", parentOrganization); + +// or use OrganizationDistinguishedName +_ldapManager.AddUserToOrganization("nameA", "passwordA", "OU=Domain Controllers,DC=yourdomain,DC=com,DC=cn"); +``` + +# More + +See [unit test](../../test/Volo.Abp.Ldap.Tests) \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/pl.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/pl.json new file mode 100644 index 0000000000..eef572eb13 --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/pl.json @@ -0,0 +1,20 @@ +{ + "culture": "pl", + "texts": { + "'{0}' and '{1}' do not match.": "'{0}' i '{1}' nie są takie same.", + "The {0} field is not a valid credit card number.": "Pole {0} nie jest poprawnym numerem karty kredytowej.", + "{0} is not valid.": "{0} jest niepoprawne.", + "The {0} field is not a valid e-mail address.": "Pole {0} nie jest poprawnym adresem e-mail.", + "The {0} field only accepts files with the following extensions: {1}": "Polr {0} przyjmuje pliki tylko z następującymi rozszerzeniami: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "Pole {0} musi być łańcuchem znaków lub talicą o maksymalnej długości '{1}'.", + "The field {0} must be a string or array type with a minimum length of '{1}'.": "Pole {0} musi być łańcuchem znaków lub talicą o minimalnej długości '{1}'.", + "The {0} field is not a valid phone number.": "Pole {0} nie jest poprawnym numerem telefonu.", + "The field {0} must be between {1} and {2}.": "Pole {0} musi być pomiędzy {1} i {2}.", + "The field {0} must match the regular expression '{1}'.": "Pole {0} musi pasować do wyrażenia regularnego '{1}'.", + "The {0} field is required.": "Pole {0} jest wymagane.", + "The field {0} must be a string with a maximum length of {1}.": "Pole {0} musi być łańcuchem znaków o maksymalnej długości {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "Pole {0} musi być łańcuchem znaków o minimalnej długości {2} i maksymalnej długości {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "Pole {0} nie jest prawidłowym, w pełni kwalifikowanym adresem URL http, https lub ftp.", + "The field {0} is invalid.": "Pole {0} jest niepoprawne." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/vi.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/vi.json new file mode 100644 index 0000000000..2d9c0c55f5 --- /dev/null +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpValidation/vi.json @@ -0,0 +1,19 @@ +{ + "culture": "vi", + "texts": { + "'{0}' and '{1}' do not match.": "'{0}' và '{1}' không khớp.", + "The {0} field is not a valid credit card number.": "Trường {0} không phải là một số thẻ tín dụng hợp lệ.", + "{0} is not valid.": "{0} không hợp lệ.", + "The {0} field is not a valid e-mail address.": "Trường {0} không phải là một địa chỉ email hợp lệ.", + "The {0} field only accepts files with the following extensions: {1}": "Trường {0} chỉ chấp nhận các tập tin có phần mở rộng như sau: {1}", + "The field {0} must be a string or array type with a maximum length of '{1}'.": "Trường {0} phải là một chuỗi hoặc một mảng với độ dài tối đa là '{1}'.", + "The {0} field is not a valid phone number.": "Trường {0} không phải là một số điện thoại hợp lệ", + "The field {0} must be between {1} and {2}.": "Trường {0} phải ở giữa {1} and {2}.", + "The field {0} must match the regular expression '{1}'.": "Trường {0} phải khớp với biểu thức chính quy '{1}'.", + "The {0} field is required.": "Trường {0} là bắt buộc.", + "The field {0} must be a string with a maximum length of {1}.": "Trường {0} phải là một chuỗi với độ dài tối đa là {1}.", + "The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.": "Trường {0} phải là một chuỗi với độ dài tối thiểu {2} và tối đa là {1}.", + "The {0} field is not a valid fully-qualified http, https, or ftp URL.": "Trường {0} không phải là một http, https, hoặc ftp URL đủ điều kiện hợp lệ.", + "The field {0} is invalid.": "Trường {0} không có hiệu lực" + } +} diff --git a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj index 9492e6fbf3..0610e45bfd 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj +++ b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/pl.json b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/pl.json new file mode 100644 index 0000000000..557d01eb31 --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + "Menu:Administration": "Administracja" + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/vi.json b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/vi.json new file mode 100644 index 0000000000..c5bf1c5ccd --- /dev/null +++ b/framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/Localization/Resource/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + "Menu:Administration": "Quản trị" + } +} diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl.json new file mode 100644 index 0000000000..5f369760a1 --- /dev/null +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/pl.json @@ -0,0 +1,51 @@ +{ + "culture": "pl", + "texts": { + "InternalServerErrorMessage": "Błąd wewnętrzny serwera podczas przetwarzania żądania!", + "ValidationErrorMessage": "Twoje żądanie jest niepoprawnie!", + "ValidationNarrativeErrorMessageTitle": "Wykryto następujące błędy podczas walidacji.", + "DefaultErrorMessage": "Wystąpił błąd!", + "DefaultErrorMessageDetail": "Treść błędu nie została wysłana z serwera.", + "DefaultErrorMessage401": "Nie jesteś zalogowany!", + "DefaultErrorMessage401Detail": "Musisz się zalogować, aby wykonać tą operację.", + "DefaultErrorMessage403": "Nie jesteś zautentykowany!", + "DefaultErrorMessage403Detail": "Nie masz uprawnień do wykonania tej operacji!", + "DefaultErrorMessage404": "Nie znaleziono zasobu!", + "DefaultErrorMessage404Detail": "Nie znaleziono zasobu z żądania na serwerze!", + "EntityNotFoundErrorMessage": "Nie istnieje encja {0} z id = {1}!", + "Error": "Błąd", + "AreYouSure": "Czy jesteś pewien?", + "Cancel": "Anuluj", + "Yes": "Tak", + "No": "Nie", + "Close": "Zamknij", + "Save": "Zapisz", + "SavingWithThreeDot": "Zapisywanie...", + "Actions": "Akcje", + "Delete": "Usuń", + "Edit": "Edytuj", + "Refresh": "Odśwież", + "ProcessingWithThreeDot": "Procesowanie...", + "LoadingWithThreeDot": "Ładowanie...", + "Welcome": "Witaj", + "Login": "Zaloguj", + "Register": "Zarejestruj", + "Logout": "Wyloguj", + "Submit": "Wyślij", + "Back": "Cofnij", + "PagerSearch": "Szukaj", + "PagerNext": "Następna", + "PagerPrevious": "Poprzednia", + "PagerFirst": "Pierwsza", + "PagerLast": "Ostatnia", + "PagerInfo": "Pokaż od _START_ do _END_ z _TOTAL_ rekordów", + "PagerInfoEmpty": "Pokaż od 0 do 0 z 0 rekordów", + "PagerInfoFiltered": "(filtruj od _MAX_ wszystkich rekordów)", + "NoDataAvailableInDatatable": "Nie znaleziono danych w tabeli", + "PagerShowMenuEntries": "Pokaż _MENU_ rekordów", + "DatatableActionDropdownDefaultText": "Akcje", + "ChangePassword": "Zmień hasło", + "PersonalInfo": "Mój profil", + "AreYouSureYouWantToCancelEditingWarningMessage": "Masz niezapisane zmiany." + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json new file mode 100644 index 0000000000..21a466ccda --- /dev/null +++ b/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/vi.json @@ -0,0 +1,51 @@ +{ + "culture": "vi", + "texts": { + "InternalServerErrorMessage": "Có một lỗi nội bộ xảy ra trong quá trình thực hiện yêu cầu của bạn!", + "ValidationErrorMessage": "Yêu cầu của bạn không hợp lệ!", + "ValidationNarrativeErrorMessageTitle": "Các lỗi sau đây đã được phát hiện trong quá trình xác nhận", + "DefaultErrorMessage": "Một lỗi đã xảy ra", + "DefaultErrorMessageDetail": "Chi tiết lỗi không được gửi bởi máy chủ", + "DefaultErrorMessage401": "Bạn chưa được xác thực", + "DefaultErrorMessage401Detail": "Bạn cần đăng nhập để thực hiện thao tác này.", + "DefaultErrorMessage403": "Bạn không được phép!", + "DefaultErrorMessage403Detail": "Bạn không được phép thực hiện thao tác này!", + "DefaultErrorMessage404": "Tài nguyên không tìm thấy!", + "DefaultErrorMessage404Detail": "Tài nguyên được yêu cầu không được tìm thấy trên máy chủ!", + "EntityNotFoundErrorMessage": "Không có thực thể nào {0} với id = {1}!", + "Error": "Lỗi", + "AreYouSure": "Bạn có chắc không ?", + "Cancel": "Hủy bỏ", + "Yes": "Đồng ý", + "No": "Không", + "Close": "Đóng", + "Save": "Lưu", + "SavingWithThreeDot": "Đang lưu...", + "Actions": "Hành động", + "Delete": "Xóa", + "Edit": "Sửa", + "Refresh": "Làm mới", + "ProcessingWithThreeDot": "Đang xử lý...", + "LoadingWithThreeDot": "Đang tải...", + "Welcome": "Chào mừng bạn", + "Login": "Đăng nhập", + "Register": "Đăng ký", + "Logout": "Đăng xuất", + "Submit": "Gửi", + "Back": "Quay lại", + "PagerSearch": "Tìm kiếm", + "PagerNext": "Trang kế", + "PagerPrevious": "Trang trước", + "PagerFirst": "Trang đầu", + "PagerLast": "Trang cuối", + "PagerInfo": "Hiển thị từ _START_ đến _END_ trong _TOTAL_ mục", + "PagerInfoEmpty": "Hiển thị từ 0 đến 0 trong 0 mục", + "PagerInfoFiltered": "(được lọc từ tổng số _MAX_ mục)", + "NoDataAvailableInDatatable": "Không có dữ liệu trong bảng", + "PagerShowMenuEntries": "Hiển thị _MENU_ mục", + "DatatableActionDropdownDefaultText": "Hành động", + "ChangePassword": "Đổi mật khẩu", + "PersonalInfo": "Hồ sơ của tôi", + "AreYouSureYouWantToCancelEditingWarningMessage": "Bạn có những thay đổi chưa được lưu" + } +} diff --git a/framework/test/AbpTestBase/AbpTestBase.csproj b/framework/test/AbpTestBase/AbpTestBase.csproj index 4a25e99676..3aeaf7bd7d 100644 --- a/framework/test/AbpTestBase/AbpTestBase.csproj +++ b/framework/test/AbpTestBase/AbpTestBase.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj index 806e426f82..b76e89b5d6 100644 --- a/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Authentication.OAuth.Tests/Volo.Abp.AspNetCore.Authentication.OAuth.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj index b0d3baaad9..4142fa7f39 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo.Abp.AspNetCore.MultiTenancy.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj index bd0a8c1ca0..ea9514a9cb 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo.Abp.AspNetCore.Mvc.Tests.csproj @@ -21,7 +21,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/pl.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/pl.json new file mode 100644 index 0000000000..c794c9c123 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/pl.json @@ -0,0 +1,7 @@ +{ + "culture": "pl", + "texts": { + "BirthDate": "Data urodzenia", + "Value1": "Wartość jeden" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/vi.json b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/vi.json new file mode 100644 index 0000000000..046b7893f3 --- /dev/null +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/Localization/Resource/vi.json @@ -0,0 +1,7 @@ +{ + "culture": "vi", + "texts": { + "BirthDate": "Ngày sinh", + "Value1": "Giá trị thứ nhất" + } +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj index a25b7d7d8f..93b64b0632 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Tests.csproj @@ -20,7 +20,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj index 74c0285f34..2404de7777 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo.Abp.AspNetCore.Mvc.UI.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj index d32284ed87..2d0ddd9412 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Versioning.Tests/Volo.Abp.AspNetCore.Mvc.Versioning.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj index 9c7544a2f6..e1d676335a 100644 --- a/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Tests/Volo.Abp.AspNetCore.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj b/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj index cb099c5168..4034493fc7 100644 --- a/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj +++ b/framework/test/Volo.Abp.Auditing.Tests/Volo.Abp.Auditing.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj b/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj index 88925bb67d..40c4907756 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj +++ b/framework/test/Volo.Abp.Authorization.Tests/Volo.Abp.Authorization.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj b/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj index 9eb89d4af9..e2f7ed2cfd 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj @@ -14,7 +14,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj b/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj index c92d40f8be..6c1a23c66f 100644 --- a/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj +++ b/framework/test/Volo.Abp.Autofac.Tests/Volo.Abp.Autofac.Tests.csproj @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj index 7fa0474264..fea03fb2cf 100644 --- a/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj +++ b/framework/test/Volo.Abp.BackgroundJobs.Tests/Volo.Abp.BackgroundJobs.Tests.csproj @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj b/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj index 2b4696092c..3fd378b759 100644 --- a/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj +++ b/framework/test/Volo.Abp.Caching.Tests/Volo.Abp.Caching.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj b/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj index c5a45236c2..35b9edf31f 100644 --- a/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj +++ b/framework/test/Volo.Abp.Castle.Core.Tests/Volo.Abp.Castle.Core.Tests.csproj @@ -14,7 +14,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj b/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj index bb2664cdc1..0fae5b99d4 100644 --- a/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj +++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo.Abp.Cli.Core.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj b/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj index bd58cb0d71..119ef18d83 100644 --- a/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj +++ b/framework/test/Volo.Abp.Core.Tests/Volo.Abp.Core.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj b/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj index 13c9cb2ef3..7862e4e0ef 100644 --- a/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj +++ b/framework/test/Volo.Abp.Data.Tests/Volo.Abp.Data.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj b/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj index ad4141f96f..802d8a53b0 100644 --- a/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj +++ b/framework/test/Volo.Abp.Ddd.Tests/Volo.Abp.Ddd.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj index ca155ab951..d8b058f05a 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj @@ -21,7 +21,7 @@ - + diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pl.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pl.json new file mode 100644 index 0000000000..6dd6654aa1 --- /dev/null +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + "hello": "witaj" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/vi.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/vi.json new file mode 100644 index 0000000000..8261599d78 --- /dev/null +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + "hello": "xin chào" + } +} diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj index 3f32baa6aa..87cf70501a 100644 --- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj +++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo.Abp.EntityFrameworkCore.Tests.csproj @@ -21,7 +21,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj b/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj index e810d5ef76..ac8c0ef36f 100644 --- a/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj +++ b/framework/test/Volo.Abp.EventBus.Tests/Volo.Abp.EventBus.Tests.csproj @@ -17,7 +17,7 @@ - + diff --git a/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj b/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj index ece1f124d5..02c7475eb0 100644 --- a/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj +++ b/framework/test/Volo.Abp.Features.Tests/Volo.Abp.Features.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj b/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj index b0bc864896..999d06d67c 100644 --- a/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj +++ b/framework/test/Volo.Abp.FluentValidation.Tests/Volo.Abp.FluentValidation.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj b/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj index 4997863830..aff0575607 100644 --- a/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj +++ b/framework/test/Volo.Abp.Http.Client.Tests/Volo.Abp.Http.Client.Tests.csproj @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo.Abp.Ldap.Tests.csproj b/framework/test/Volo.Abp.Ldap.Tests/Volo.Abp.Ldap.Tests.csproj new file mode 100644 index 0000000000..c221b309c4 --- /dev/null +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo.Abp.Ldap.Tests.csproj @@ -0,0 +1,18 @@ + + + + netcoreapp2.2 + latest + false + + + + + + + + + + + + diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/Authenticate_Tests.cs b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/Authenticate_Tests.cs new file mode 100644 index 0000000000..35f631b8d2 --- /dev/null +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/Authenticate_Tests.cs @@ -0,0 +1,70 @@ +using System; +using Shouldly; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.Abp.Ldap +{ + + public class Authenticate_Tests : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + private readonly ILdapManager _ldapManager; + private readonly LdapTestData _testData; + + public Authenticate_Tests() + { + // ReSharper disable once VirtualMemberCallInConstructor + _testData = GetRequiredService(); + _ldapManager = GetRequiredService(); + } + + [Fact(Skip = "need environment AD ")] + public void Authenticate() + { + var result = _ldapManager.Authenticate(_testData.AdministratorDomainName, _testData.AdministratorPassword); + + result.ShouldBeTrue(); + } + + [Fact(Skip = "need environment AD ")] + public void Authenticate_With_Wrong_Password() + { + var result = _ldapManager.Authenticate("NonExistentNameA", "PasswordA"); + + result.ShouldBeFalse(); + } + + [DependsOn(typeof(AbpLdapModule))] + public class TestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + // not use ssl + // "LDAP": { + // "ServerHost": "192.168.101.54", + // "ServerPort": 389, + // "UseSSL": false + // } + + // use ssl + // "LDAP": { + // "ServerHost": "192.168.101.54", + // "ServerPort": 636, + // "UseSSL": true + // } + Configure(settings => + { + settings.ServerHost = "192.168.101.54"; + settings.ServerPort = 636; + settings.UseSsl = true; + }); + } + } + } + +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapHelps_Tests.cs b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapHelps_Tests.cs new file mode 100644 index 0000000000..06d6834992 --- /dev/null +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapHelps_Tests.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using Shouldly; +using Xunit; + +namespace Volo.Abp.Ldap +{ + public class LdapHelps_Tests + { + + [Fact] + public void BuildCondition_With_Value() + { + // act + var res = LdapHelps.BuildCondition("objectClass", "testNameA"); + + // assert + res.ShouldBe("(objectClass=testNameA)"); + } + + [Fact] + public void BuildCondition_With_Null_Value() + { + // act + var res = LdapHelps.BuildCondition("objectClass", null); + + // assert + res.ShouldBeEmpty(); + } + + [Fact] + public void BuildCondition_With_Empty_Value() + { + // act + var res = LdapHelps.BuildCondition("objectClass", ""); + + // assert + res.ShouldBeEmpty(); + } + + [Fact] + public void BuildCondition_With_WhiteSpace_Value() + { + // act + var res = LdapHelps.BuildCondition("objectClass", " "); + + // assert + res.ShouldBeEmpty(); + } + + [Fact] + public void BuildFilter_With_Null_Condition() + { + // act + var res = LdapHelps.BuildFilter(null); + + // assert + res.ShouldBe("(&(objectClass=*))"); + } + + [Fact] + public void BuildFilter_With_Empty_Condition() + { + // act + var res = LdapHelps.BuildFilter(new Dictionary()); + + // assert + res.ShouldBe("(&(objectClass=*))"); + } + + [Fact] + public void BuildFilter_With_Condition() + { + // act + var conditions = new Dictionary + { + {"objectClass", "testClassA"}, {"objectCategory", "testCategoryA"}, {"name", null} + }; + var res = LdapHelps.BuildFilter(conditions); + + // assert + res.ShouldBe("(&(objectClass=testClassA)(objectCategory=testCategoryA))"); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapManager_Tests.cs b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapManager_Tests.cs new file mode 100644 index 0000000000..00d9287c4f --- /dev/null +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapManager_Tests.cs @@ -0,0 +1,245 @@ +using System; +using Shouldly; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.Abp.Ldap +{ + + public class LdapManager_Tests : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + private readonly ILdapManager _ldapManager; + private readonly LdapTestData _testData; + + public LdapManager_Tests() + { + // ReSharper disable once VirtualMemberCallInConstructor + _testData = GetRequiredService(); + _ldapManager = GetRequiredService(); + } + + [Fact(Skip = "need environment AD ")] + public void GetOrganizations_With_Empty_Condition() + { + var result = _ldapManager.GetOrganizations(); + + result.ShouldNotBeNull(); + result.ShouldContain(e => e.Name == _testData.DomainControllersName); + result.ShouldContain(e => e.DistinguishedName == _testData.DomainControllersDistinguishedName); + } + + [Fact(Skip = "need environment AD ")] + public void GetOrganizations_With_Name() + { + var result = _ldapManager.GetOrganizations(_testData.DomainControllersName); + + result.ShouldNotBeNull(); + result.ShouldHaveSingleItem(); + result.ShouldContain(e => e.Name == _testData.DomainControllersName); + result.ShouldContain(e => e.DistinguishedName == _testData.DomainControllersDistinguishedName); + } + + [Fact(Skip = "need environment AD ")] + public void GetOrganizations_With_Non_Existent_Name() + { + var result = _ldapManager.GetOrganizations("NonExistentNameA"); + + result.ShouldNotBeNull(); + result.ShouldBeEmpty(); + } + + [Fact(Skip = "need environment AD ")] + public void GetOrganization() + { + var result = _ldapManager.GetOrganization(_testData.DomainControllersDistinguishedName); + + result.ShouldNotBeNull(); + result.Name.ShouldBe(_testData.DomainControllersName); + } + + [Fact(Skip = "need environment AD ")] + public void GetOrganization_With_Non_Existent_DistinguishedName() + { + var result = _ldapManager.GetOrganization("NonExistentNameA"); + + result.ShouldBeNull(); + } + + [Fact(Skip = "need environment AD ")] + public void GetUsers_With_Empty_Condition() + { + var result = _ldapManager.GetUsers(); + + result.ShouldNotBeNull(); + result.ShouldContain(e => e.Name == _testData.AdministratorName); + } + + [Fact(Skip = "need environment AD ")] + public void GetUsers_With_Name() + { + var result = _ldapManager.GetUsers(name: _testData.AdministratorName); + + result.ShouldNotBeNull(); + result.ShouldContain(e => e.Name == _testData.AdministratorName); + } + + [Fact(Skip = "need environment AD ")] + public void GetUsers_With_Non_Existent_Name() + { + var result = _ldapManager.GetUsers(name: "NonExistentNameA"); + + result.ShouldNotBeNull(); + result.ShouldBeEmpty(); + } + + [Fact(Skip = "need environment AD ")] + public void GetUsers_With_CommonName() + { + var result = _ldapManager.GetUsers(commonName: _testData.AdministratorName); + + result.ShouldNotBeNull(); + result.ShouldContain(e => e.Name == _testData.AdministratorName); + } + + [Fact(Skip = "need environment AD ")] + public void GetUsers_With_Non_Existent_CommonName() + { + var result = _ldapManager.GetUsers(commonName: "NonExistentNameA"); + + result.ShouldNotBeNull(); + result.ShouldBeEmpty(); + } + + [Fact(Skip = "need environment AD ")] + public void GetUsers_With_DisplayName() + { + var result = _ldapManager.GetUsers(displayName: _testData.AdministratorName); + + result.ShouldNotBeNull(); + // the administrator in AD. not have display name by default. + result.ShouldBeEmpty(); + } + + [Fact(Skip = "need environment AD ")] + public void GetUser() + { + var result = _ldapManager.GetUser(_testData.AdministratorDistinguishedName); + + result.ShouldNotBeNull(); + result.Name.ShouldBe(_testData.AdministratorName); + } + + [Fact(Skip = "need environment AD ")] + public void GetUser_With_Non_Existent_DistinguishedName() + { + var result = _ldapManager.GetOrganization("NonExistentNameA"); + + result.ShouldBeNull(); + } + + [Fact(Skip = "need environment AD ")] + public void Authenticate() + { + var result = _ldapManager.Authenticate(_testData.AdministratorDomainName, _testData.AdministratorPassword); + + result.ShouldBeTrue(); + } + + [Fact(Skip = "need environment AD ")] + public void Authenticate_With_Wrong_Password() + { + var result = _ldapManager.Authenticate("NonExistentNameA", "PasswordA"); + + result.ShouldBeFalse(); + } + + [Fact(Skip = "need environment AD ")] + public void AddSubOrganization() + { + var parentOrganization = _ldapManager.GetOrganization(_testData.DomainControllersDistinguishedName); + var randomName = $"Test_{DateTime.Now.Ticks}"; + + _ldapManager.AddSubOrganization(randomName, parentOrganization); + + var result = _ldapManager.GetOrganizations(randomName); + result.ShouldNotBeNull(); + result.ShouldContain(e => e.Name == randomName); + } + + [Fact(Skip = "need environment AD ")] + public void AddSubOrganization_With_DistinguishedName() + { + var randomName = $"Test_{DateTime.Now.Ticks}"; + + _ldapManager.AddSubOrganization(randomName, _testData.DomainControllersDistinguishedName); + + var result = _ldapManager.GetOrganizations(randomName); + result.ShouldNotBeNull(); + result.ShouldContain(e => e.Name == randomName); + } + + [Fact(Skip = "need environment AD ")] + public void AddOrganizationUser() + { + var parentOrganization = _ldapManager.GetOrganization(_testData.DomainControllersDistinguishedName); + var randomName = $"Test_{DateTime.Now:yyMMddHHmmss}"; + _ldapManager.AddUserToOrganization(randomName, _testData.AdministratorPassword, parentOrganization); + + var result = _ldapManager.GetUsers(randomName); + result.ShouldNotBeNull(); + result.ShouldContain(e=>e.Name == randomName); + } + + [DependsOn(typeof(AbpLdapModule))] + public class TestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + // not use ssl + // "LDAP": { + // "ServerHost": "192.168.101.54", + // "ServerPort": 389, + // "UseSSL": false, + // "Credentials": { + // "DomainUserName": "administrator@yourdomain.com.cn", + // "Password": "yH.20190528" + // }, + // "SearchBase": "CN=Users,DC=yourdomain,DC=com,DC=cn", + // "DomainName": "yourdomain.com.cn", + // "DomainDistinguishedName": "DC=yourdomain,DC=com,DC=cn" + // } + + // use ssl + // "LDAP": { + // "ServerHost": "192.168.101.54", + // "ServerPort": 636, + // "UseSSL": true, + // "Credentials": { + // "DomainUserName": "administrator@yourdomain.com.cn", + // "Password": "yH.20190528" + // }, + // "SearchBase": "CN=Users,DC=yourdomain,DC=com,DC=cn", + // "DomainName": "yourdomain.com.cn", + // "DomainDistinguishedName": "DC=yourdomain,DC=com,DC=cn" + // } + Configure(settings => + { + settings.ServerHost = "192.168.101.54"; + settings.ServerPort = 636; + settings.UseSsl = true; + settings.Credentials.DomainUserName = "administrator@yourdomain.com.cn"; + settings.Credentials.Password = "yH.20190528"; + settings.SearchBase = "DC=yourdomain,DC=com,DC=cn"; + settings.DomainName = "yourdomain.com.cn"; + settings.DomainDistinguishedName = "DC=yourdomain,DC=com,DC=cn"; + }); + } + } + } + +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapTestData.cs b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapTestData.cs new file mode 100644 index 0000000000..8224686daa --- /dev/null +++ b/framework/test/Volo.Abp.Ldap.Tests/Volo/Abp/Ldap/LdapTestData.cs @@ -0,0 +1,27 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.Ldap +{ + public class LdapTestData : ISingletonDependency + { + public string AdministratorName { get; } = "Administrator"; + public string AdministratorPassword { get; } = "yH.20190528"; + public string AdministratorDistinguishedName { get; } = "CN=Administrator,CN=Users,DC=yourdomain,DC=com,DC=cn"; + public string AdministratorDomainName { get; } = "Administrator@yourdomain.com.cn"; + + public string DomainControllersName = "Domain Controllers"; + public string DomainControllersDistinguishedName = "OU=Domain Controllers,DC=yourdomain,DC=com,DC=cn"; + + public string RootDistinguishedName { get; } = "DC=yourdomain,DC=com,DC=cn"; + + public string Organization001Name { get; } = "Test_A"; + + public string Test001Name { get; } = "test001"; + public string Test001Password { get; } = "yH.20190528"; + public string Test001Email { get; } = "test001@yourdomain.com.cn"; + + public string Test002Name { get; } = "test002"; + public string Test002Password { get; } = "yH.20190528"; + public string Test002WrongPassword { get; } = "yH.20190529"; + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj b/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj index 98a01e2fc7..1decc345f4 100644 --- a/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj +++ b/framework/test/Volo.Abp.Localization.Tests/Volo.Abp.Localization.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/pl.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/pl.json new file mode 100644 index 0000000000..5e343cf2f9 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/pl.json @@ -0,0 +1,7 @@ +{ + "culture": "pl", + "texts": { + "USA": "Stany Zjednoczone Ameryki", + "Brazil": "Brazylia" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/vi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/vi.json new file mode 100644 index 0000000000..a429f8295b --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/CountryNames/vi.json @@ -0,0 +1,7 @@ +{ + "culture": "vi", + "texts": { + "USA": "Nước Mỹ", + "Brazil": "Brazil" + } +} diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/pl.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/pl.json new file mode 100644 index 0000000000..1d0bfdf66a --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/pl.json @@ -0,0 +1,7 @@ +{ + "culture": "pl", + "texts": { + "ThisFieldIsRequired": "To pole jest wymagane", + "MaxLenghtErrorMessage": "To pole może mieć maksymalnie '{0}' znaków" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/vi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/vi.json new file mode 100644 index 0000000000..583eebab13 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Base/Validation/vi.json @@ -0,0 +1,7 @@ +{ + "culture": "vi", + "texts": { + "ThisFieldIsRequired": "Trường này là bắt buộc", + "MaxLenghtErrorMessage": "Trường này có thể có tối đa là '{0}' kí tự" + } +} diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/pl.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/pl.json new file mode 100644 index 0000000000..d014bc7b30 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/pl.json @@ -0,0 +1,11 @@ +{ + "culture": "pl", + "texts": { + "Hello {0}.": "Witaj {0}.", + "Car": "Samochód", + "CarPlural": "Samochody", + "MaxLenghtErrorMessage": "To pole może mieć maksymalnie '{0}' znaków", + "Universe": "Wszechświat", + "FortyTwo": "Czterdzieści dwa" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/vi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/vi.json new file mode 100644 index 0000000000..6f5bff743c --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/Source/vi.json @@ -0,0 +1,11 @@ +{ + "culture": "vi", + "texts": { + "Hello {0}.": "Xin chào {0}.", + "Car": "Car", + "CarPlural": "Cars", + "MaxLenghtErrorMessage": "Kích thước trường này có tối đa '{0}' kí tự", + "Universe": "Vũ trụ", + "FortyTwo": "Bốn mươi hai" + } +} diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/pl.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/pl.json new file mode 100644 index 0000000000..2935790010 --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + "SeeYou": "Do zobaczenia" + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/vi.json b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/vi.json new file mode 100644 index 0000000000..d4d350246f --- /dev/null +++ b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TestResources/SourceExt/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + "SeeYou": "Hẹn gặp lại" + } +} diff --git a/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj b/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj index 062cfaf730..1d83b1e54f 100644 --- a/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj +++ b/framework/test/Volo.Abp.MemoryDb.Tests/Volo.Abp.MemoryDb.Tests.csproj @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj b/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj index 5ca5401bac..a99a675193 100644 --- a/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj +++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo.Abp.MongoDB.Tests.csproj @@ -19,8 +19,8 @@ - - + + \ No newline at end of file diff --git a/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj b/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj index 631ad1ed81..16c27a26a6 100644 --- a/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj +++ b/framework/test/Volo.Abp.MultiTenancy.Tests/Volo.Abp.MultiTenancy.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj b/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj index 5339246c52..46b4c9e952 100644 --- a/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj +++ b/framework/test/Volo.Abp.Security.Tests/Volo.Abp.Security.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj b/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj index 99db6083c2..a7325c95c0 100644 --- a/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj +++ b/framework/test/Volo.Abp.Serialization.Tests/Volo.Abp.Serialization.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj index 1e9bd3f4a0..76f2d05afa 100644 --- a/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj +++ b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj b/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj index 6f2cbe09f8..e3f35153f9 100644 --- a/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj +++ b/framework/test/Volo.Abp.Specifications.Tests/Volo.Abp.Specifications.Tests.csproj @@ -15,7 +15,7 @@ - + \ No newline at end of file diff --git a/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj b/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj index 3985910708..51b60b693f 100644 --- a/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj +++ b/framework/test/Volo.Abp.TestApp.Tests/Volo.Abp.TestApp.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj b/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj index 4e7b58ee84..3da0bcd7ce 100644 --- a/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj +++ b/framework/test/Volo.Abp.TestApp/Volo.Abp.TestApp.csproj @@ -18,7 +18,7 @@ - + diff --git a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj index 10318fbf90..4fa8929ed4 100644 --- a/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj +++ b/framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj b/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj index f3dede4b21..574891cc27 100644 --- a/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj +++ b/framework/test/Volo.Abp.Uow.Tests/Volo.Abp.Uow.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj b/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj index 60308b96ae..7fb87036e2 100644 --- a/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj +++ b/framework/test/Volo.Abp.Validation.Tests/Volo.Abp.Validation.Tests.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj index 895b8231ce..d69c461c29 100644 --- a/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj +++ b/framework/test/Volo.Abp.VirtualFileSystem.Tests/Volo.Abp.VirtualFileSystem.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/modules/account/src/Volo.Abp.Account.Web/Localization/Resources/AbpAccount/Web/pl.json b/modules/account/src/Volo.Abp.Account.Web/Localization/Resources/AbpAccount/Web/pl.json new file mode 100644 index 0000000000..b661af8050 --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Localization/Resources/AbpAccount/Web/pl.json @@ -0,0 +1,21 @@ +{ + "culture": "pl", + "texts": { + "UserName": "Nazwa użytkownika", + "EmailAddress": "Adres email", + "UserNameOrEmailAddress": "Nazwa użytkownia lub adres email", + "Password": "Hasło", + "RememberMe": "Zapamiętaj mnie", + "UseAnotherServiceToLogin": "Użyj innej usługi do zalogowania się", + "UserLockedOutMessage": "Konto użytkownika zostało zablokowane po nieudanych próbach zalogowania. Odczekaj chwilę i spróbuj ponownie.", + "InvalidUserNameOrPassword": "Niepoprawna nazwa użytkownika lub hasło!", + "LoginIsNotAllowed": "Nie jesteś uprawniony do logowania! Musisz potwierdzić swój email/numer telefonu.", + "SelfRegistrationDisabledMessage": "Rejestracja użytkowników jest wyłączona dla tej aplikacji. Skontaktuj się z administratorem aplikacji w celu rejestracji nowego użytkownika.", + "Login": "Zaloguj", + "Cancel": "Anuluj", + "Register": "Zarejestruj", + "InvalidLoginRequest": "Logowanie nieudane", + "ThereAreNoLoginSchemesConfiguredForThisClient": "Nie istnieje skonfigurany schemat logowania dla użytkownika.", + "LogInUsingYourProviderAccount": "Zaloguj używając konta {0}" + } +} \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Web/Localization/Resources/AbpAccount/Web/vi.json b/modules/account/src/Volo.Abp.Account.Web/Localization/Resources/AbpAccount/Web/vi.json new file mode 100644 index 0000000000..56d436c1cd --- /dev/null +++ b/modules/account/src/Volo.Abp.Account.Web/Localization/Resources/AbpAccount/Web/vi.json @@ -0,0 +1,21 @@ +{ + "culture": "vi", + "texts": { + "UserName": "Tên đăng nhập", + "EmailAddress": "Địa chỉ email", + "UserNameOrEmailAddress": "Tên đăng nhập hoặc địa chỉ email", + "Password": "Mật khẩu", + "RememberMe": "Ghi nhớ", + "UseAnotherServiceToLogin": "Sử dụng dịch vụ khác để đăng nhập", + "UserLockedOutMessage": "Tài khoản người dùng đã bị khóa do các nỗ lực đăng nhập không hợp lệ. Xin vui lòng chờ một lúc và thử lại.", + "InvalidUserNameOrPassword": "Sai tên tài khoản hoặc mật khẩu!", + "LoginIsNotAllowed": "Bạn không được phép đăng nhập! Bạn cần xác nhận email/số điện thoại của bạn.", + "SelfRegistrationDisabledMessage": "Tự đăng ký người dùng bị vô hiệu hóa cho ứng dụng này. Liên hệ với quản trị viên ứng dụng để đăng ký người dùng mới.", + "Login": "Đăng nhập", + "Cancel": "Hủy bỏ", + "Register": "Đăng ký", + "InvalidLoginRequest": "Yêu cầu đăng nhập không hợp lệ", + "ThereAreNoLoginSchemesConfiguredForThisClient": "Không có chương trình đăng nhập được cấu hình cho khách hàng này.", + "LogInUsingYourProviderAccount": "Đăng nhập bằng tài khoản {0} của bạn" + } +} diff --git a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.csproj b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.csproj index 8134b0c512..515f5d37f6 100644 --- a/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.csproj +++ b/modules/background-jobs/app/Volo.Abp.BackgroundJobs.DemoApp.HangFire/Volo.Abp.BackgroundJobs.DemoApp.HangFire.csproj @@ -6,7 +6,7 @@ - + diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj index a8ff824305..66ef602232 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.Domain.Tests/Volo.Abp.BackgroundJobs.Domain.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj index 722d94f88e..7fd7558b02 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests/Volo.Abp.BackgroundJobs.EntityFrameworkCore.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj index f3fb433d10..e999356678 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.MongoDB.Tests/Volo.Abp.BackgroundJobs.MongoDB.Tests.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj index 1f4db1af41..ce6e3b7c1b 100644 --- a/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj +++ b/modules/background-jobs/test/Volo.Abp.BackgroundJobs.TestBase/Volo.Abp.BackgroundJobs.TestBase.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/pl.json b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/pl.json new file mode 100644 index 0000000000..8806854643 --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/pl.json @@ -0,0 +1,14 @@ +{ + "culture": "pl", + "texts": { + "Permission:Blogging": "Blog", + "Permission:Blogs": "Blogi", + "Permission:Posts": "Posty", + "Permission:Tags": "Tagi", + "Permission:Comments": "Komentarze", + "Permission:Management": "Zarządzanie", + "Permission:Edit": "Edytuj", + "Permission:Create": "Utwórz", + "Permission:Delete": "Usuń" + } +} \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/vi.json b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/vi.json new file mode 100644 index 0000000000..a32ee04bb9 --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Localization/Resources/Blogging/ApplicationContracts/vi.json @@ -0,0 +1,14 @@ +{ + "culture": "vi", + "texts": { + "Permission:Blogging": "Blog", + "Permission:Blogs": "Blogs", + "Permission:Posts": "Bài viết", + "Permission:Tags": "Thẻ", + "Permission:Comments": "Bình luận", + "Permission:Management": "Quản lý", + "Permission:Edit": "Sửa", + "Permission:Create": "Tạo", + "Permission:Delete": "Xóa" + } +} diff --git a/modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/pl.json b/modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/pl.json new file mode 100644 index 0000000000..15e0c7eb0d --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/pl.json @@ -0,0 +1,47 @@ +{ + "culture": "pl", + "texts": { + "Menu:Blogs": "Blogi", + "Menu:BlogManagement": "Zarządzanie blogiem", + "Title": "Tytuł", + "Delete": "Usuń", + "Reply": "Odpowiedz", + "ReplyTo": "Odpowiedz {0}", + "ContinueReading": "Kontynuuj czytanie", + "DaysAgo": "{0} dni temu", + "YearsAgo": "{0} lat temu", + "MonthsAgo": "{0} miesięcy temu", + "WeeksAgo": "{0} tygodni temu", + "MinutesAgo": "{0} minut temu", + "SecondsAgo": "{0} sekund temu", + "HoursAgo": "{0} godzin temu", + "Now": "teraz", + "Content": "Treść", + "SeeAll": "Zobacz wszystko", + "PopularTags": "Popularne tagi", + "WiewsWithCount": "{0} wyświetleń", + "LastPosts": "Ostatnie wpisy", + "LeaveComment": "Zostaw komentarz", + "TagsInThisArticle": "Tagi w tym artykule", + "Posts": "Wpisy", + "Edit": "Edytuj", + "BLOG": "BLOG", + "CommentDeletionWarningMessage": "Komentarz zostanie usunięty.", + "PostDeletionWarningMessage": "Wpis zostanie usunięty.", + "BlogDeletionWarningMessage": "Blog zostanie usunięty.", + "AreYouSure": "Czy jesteś pewien?", + "CommentWithCount": "{0} komentarzy", + "Comment": "Komentarz", + "ShareOnTwitter": "Udostępnij na Twitter", + "CoverImage": "Obraz okładki", + "CreateANewPost": "Utwórz nowy wpis", + "CreateANewBlog": "Utwórz nowy blog", + "WhatIsNew": "Co nowego?", + "Name": "Nazwa", + "ShortName": "Krótka nazwa", + "CreationTime": "Data utworzenia", + "Description": "Opis", + "Blogs": "Blogi", + "Tags": "Tagi" + } +} \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/vi.json b/modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/vi.json new file mode 100644 index 0000000000..1405337271 --- /dev/null +++ b/modules/blogging/src/Volo.Blogging.Web/Localization/Resources/Blogging/Web/vi.json @@ -0,0 +1,47 @@ +{ + "culture": "vi", + "texts": { + "Menu:Blogs": "Blogs", + "Menu:BlogManagement": "Quản lý Blog", + "Title": "Tiêu đề", + "Delete": "Xóa", + "Reply": "Trả lời", + "ReplyTo": "Trả lời {0}", + "ContinueReading": "Tiếp tục đọc", + "DaysAgo": "{0} ngày trước", + "YearsAgo": "{0} năm trước", + "MonthsAgo": "{0} tháng trước", + "WeeksAgo": "{0} tuần trước", + "MinutesAgo": "{0} phút trước", + "SecondsAgo": "{0} giây trước", + "HoursAgo": "{0} giờ trước", + "Now": "bây giờ", + "Content": "Nội dung", + "SeeAll": "Xem tất cả", + "PopularTags": "Thẻ phổ biến", + "WiewsWithCount": "{0} lượt xem", + "LastPosts": "Bài viết cuối", + "LeaveComment": "Để lại bình luận", + "TagsInThisArticle": "Từ khóa trong bài viết này", + "Posts": "Bài viết", + "Edit": "Sửa", + "BLOG": "BLOG", + "CommentDeletionWarningMessage": "Bình luận sẽ bị xóa.", + "PostDeletionWarningMessage": "Bài viết sẽ bị xóa.", + "BlogDeletionWarningMessage": "Blog sẽ bị xóa.", + "AreYouSure": "Bạn chắc chứ?", + "CommentWithCount": "{0} bình luận", + "Comment": "Bình luận", + "ShareOnTwitter": "Chia sẻ Twitter", + "CoverImage": "Ảnh bìa", + "CreateANewPost": "Tạo một bài viết mới", + "CreateANewBlog": "Tạo một Blog mới", + "WhatIsNew": "Cái gì mới?", + "Name": "Tên", + "ShortName": "Tên rút gọn", + "CreationTime": "Thời gian tạo", + "Description": "Mô tả", + "Blogs": "Blogs", + "Tags": "Thẻ" + } +} diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/pl.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/pl.json new file mode 100644 index 0000000000..f131f9e139 --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/pl.json @@ -0,0 +1,9 @@ +{ + "culture": "pl", + "texts": { + "WelcomeVoloDocs": "Witaj w VoloDocs!", + "NoProjectWarning": "Nie ma jeszcze zdefiniowanego projektu!", + "CreateYourFirstProject": "Kliknij, aby rozpocząć swój pierwszy projekt", + "NoProject": "Brak projektu!" + } +} \ No newline at end of file diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/vi.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/vi.json new file mode 100644 index 0000000000..46afd97fd0 --- /dev/null +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/vi.json @@ -0,0 +1,9 @@ +{ + "culture": "vi", + "texts": { + "WelcomeVoloDocs": "Chào mừng đến với VoloDocs!", + "NoProjectWarning": "Không có dự án nào!", + "CreateYourFirstProject": "Nhấn vào đây để bắt đầu dự án đầu tiên của bạn", + "NoProject": "Không có dự án!" + } +} diff --git a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs index ccb8cce083..ec66947dd7 100644 --- a/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs +++ b/modules/docs/app/VoloDocs.Web/Pages/Index.cshtml.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Options; @@ -17,7 +18,12 @@ namespace VoloDocs.Web.Pages public IActionResult OnGet() { //TODO: Create HomeController & Index instead of Page. Otherwise, we have an empty Index.cshtml file. - return Redirect("./documents"); + if (!_urlOptions.RoutePrefix.IsNullOrWhiteSpace()) + { + return Redirect("." + _urlOptions.GetFormattedRoutePrefix()); + } + + return Page(); } } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/pl.json b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/pl.json new file mode 100644 index 0000000000..e03a79585d --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/pl.json @@ -0,0 +1,10 @@ +{ + "culture": "pl", + "texts": { + "Permission:DocumentManagement": "Zarządzanie dokumentacją", + "Permission:Projects": "Projekty", + "Permission:Edit": "Edytuj", + "Permission:Delete": "Usuń", + "Permission:Create": "Utwórz" + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/vi.sjon b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/vi.sjon new file mode 100644 index 0000000000..0697ddf6e8 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Localization/Resources/Docs/ApplicationContracts/vi.sjon @@ -0,0 +1,10 @@ +{ + "culture": "vi", + "texts": { + "Permission:DocumentManagement": "Quản lý tài liệu", + "Permission:Projects": "Dự án", + "Permission:Edit": "Sửa", + "Permission:Delete": "Xóa", + "Permission:Create": "Tạo" + } +} diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Localization/Resources/Docs/Web/pl.json b/modules/docs/src/Volo.Docs.Admin.Web/Localization/Resources/Docs/Web/pl.json new file mode 100644 index 0000000000..414d4a684f --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Web/Localization/Resources/Docs/Web/pl.json @@ -0,0 +1,27 @@ +{ + "culture": "pl", + "texts": { + "Menu:DocumentManagement": "Dokumenty", + "Menu:ProjectManagement": "Projekty", + "CreateANewProject": "Utwórz nowy projet", + "Edit": "Edytuj", + "Create": "Utwórz", + "Projects": "Projekty", + "Name": "Nazwa", + "ShortName": "Krótka nazwa", + "DocumentStoreType": "Typ zapisu dokumentu", + "Format": "Format", + "ShortNameInfoText": "Zostanie użyty do unikalnego URL.", + "DisplayName:Name": "Nazwa", + "DisplayName:ShortName": "Krótka nazwa", + "DisplayName:Format": "Format", + "DisplayName:DefaultDocumentName": "Domyślna nazwa dokumentu", + "DisplayName:NavigationDocumentName": "Nawigacyjna nazwa dokumentu", + "DisplayName:MinimumVersion": "Minimalna wersja", + "DisplayName:MainWebsiteUrl": "Adres strony głównej", + "DisplayName:LatestVersionBranchName": "Nazwa brancha ostatniej wersji", + "DisplayName:GitHubRootUrl": "Adres URL do GitHub'a", + "DisplayName:GitHubAccessToken": "GitHub access token", + "DisplayName:GitHubUserAgent": "GitHub user agent" + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Admin.Web/Localization/Resources/Docs/Web/vi.json b/modules/docs/src/Volo.Docs.Admin.Web/Localization/Resources/Docs/Web/vi.json new file mode 100644 index 0000000000..d39b27f295 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Admin.Web/Localization/Resources/Docs/Web/vi.json @@ -0,0 +1,27 @@ +{ + "culture": "vi", + "texts": { + "Menu:DocumentManagement": "Tài liệu", + "Menu:ProjectManagement": "Dự án", + "CreateANewProject": "Tạo dự án mới", + "Edit": "Sửa", + "Create": "Tạo", + "Projects": "Dự án", + "Name": "Tên", + "ShortName": "Tên rút gọn", + "DocumentStoreType": "DocumentStoreType", + "Format": "Định dạng", + "ShortNameInfoText": "Sẽ được sử dụng cho URL duy nhất..", + "DisplayName:Name": "Tên", + "DisplayName:ShortName": "Tên rút gọn", + "DisplayName:Format": "Định dạng", + "DisplayName:DefaultDocumentName": "Tên tài liệu mặc định", + "DisplayName:NavigationDocumentName": "Tên tài liệu điều hướng", + "DisplayName:MinimumVersion": "Phiên bản tối thiểu", + "DisplayName:MainWebsiteUrl": "URL trang web chính", + "DisplayName:LatestVersionBranchName": "Tên nhánh phiên bản mới nhất", + "DisplayName:GitHubRootUrl": "URL gốc của GitHub", + "DisplayName:GitHubAccessToken": "GitHub access token", + "DisplayName:GitHubUserAgent": "GitHub user agent" + } +} diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs index d0bdccac54..c2eb1bb24d 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs @@ -37,7 +37,7 @@ namespace Volo.Docs.GitHub.Documents var rawDocumentUrl = rawRootUrl + documentName; var commitHistoryUrl = project.GetGitHubUrlForCommitHistory() + documentName; var isNavigationDocument = documentName == project.NavigationDocumentName; - var editLink = rootUrl.ReplaceFirst("/tree/", "/blob/") + documentName; + var editLink = rootUrl.ReplaceFirst("/tree/", "/blob/") + languageCode + "/" + documentName; var localDirectory = ""; var fileName = documentName; diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/cs.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/cs.json index ec882e6538..4c21318fdb 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/cs.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/cs.json @@ -13,6 +13,7 @@ "Projects": "Projekt(y)", "NoProjectWarning": "Zatím zde není žádný projekt!", "DocumentNotFound": "Ups, vyžádaný dokument neexistuje!", - "NavigationDocumentNotFound": "Tato verze nemá navigační dokument!" + "NavigationDocumentNotFound": "Tato verze nemá navigační dokument!", + "DocumentNotFoundInSelectedLanguage": "Tento dokument není dostupný ve vybraném jazyce. Zobrazen dokument ve výchozím jazyce." } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json index 31d3835a3a..f399b8f151 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json @@ -13,6 +13,7 @@ "Projects": "Project(s)", "NoProjectWarning": "There are no projects yet!", "DocumentNotFound": "Oops, the requested document was not found!", - "NavigationDocumentNotFound": "This version does not have a navigation document!" + "NavigationDocumentNotFound": "This version does not have a navigation document!", + "DocumentNotFoundInSelectedLanguage": "Document in the language you wanted is not found. Document in the default language is shown." } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/es.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/es.json index 94a3eec1bd..700143ad76 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/es.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/es.json @@ -3,13 +3,17 @@ "texts": { "Documents": "Documentos", "BackToWebsite": "Regresar al sitio", - "Version": "Versión", + "Contributors": "Contribuidores", + "ShareOn": "Compartilhar no", + "Version": "Versão", "Edit": "Editar", + "Delete": "Excluir", "InThisDocument": "En este documento", "GoToTop": "Subir", "Projects": "Proyecto(s)", - "NoProjectWarning": "¡Aun no hay proyectos!", - "DocumentNotFound": "¡Oops, no se encontró el documento solicitado!", - "NavigationDocumentNotFound": "Esta versión no tiene un documento de navegación!" + "NoProjectWarning": "Não há projetos ainda!", + "DocumentNotFound": "Ups! O documento solicitado não foi encontrado!", + "NavigationDocumentNotFound": "Esta versão não possui um documento de navegação!", + "DocumentNotFoundInSelectedLanguage": "Documento no idioma desejado não foi encontrado. Documento no idioma padrão é mostrado." } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/pl.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/pl.json new file mode 100644 index 0000000000..5ba3dd6c10 --- /dev/null +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/pl.json @@ -0,0 +1,18 @@ +{ + "culture": "pl", + "texts": { + "Documents": "Dokumenty", + "BackToWebsite": "Powrót do strony", + "Contributors": "Współtwórcy", + "ShareOn": "Udostępnij", + "Version": "Wersja", + "Edit": "Edytuj", + "Delete": "Usuń", + "InThisDocument": "W tym dokumencie", + "GoToTop": "Idź do góry", + "Projects": "Projekt(y)", + "NoProjectWarning": "Projekt nie istnieje!", + "DocumentNotFound": "Oops, żądany dokument nie istnieje!", + "NavigationDocumentNotFound": "Ta wersja nie posiada tego dokumentu!" + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/pt-BR.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/pt-BR.json index 38fa49de3d..0d1157d4c3 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/pt-BR.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/pt-BR.json @@ -13,6 +13,7 @@ "Projects": "Projeto(s)", "NoProjectWarning": "Ainda não há projetos!", "DocumentNotFound": "Oops, o documento solicitado não foi encontrado", - "NavigationDocumentNotFound": "Esta versão não possui um documento de navegação!" + "NavigationDocumentNotFound": "Esta versão não possui um documento de navegação!", + "DocumentNotFoundInSelectedLanguage": "Documento no idioma desejado não foi encontrado. Documento no idioma padrão é mostrado." } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json index da39c6cce3..3f15a43046 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json @@ -13,6 +13,7 @@ "Projects": "Proje(ler)", "NoProjectWarning": "Hiç proje yok!", "DocumentNotFound": "Aradığınız döküman bulunamadı!", - "NavigationDocumentNotFound": "Bu döküman için menü bulunamadı!" + "NavigationDocumentNotFound": "Bu döküman için menü bulunamadı!", + "DocumentNotFoundInSelectedLanguage": "İstediğiniz dilde belge bulunamadı. Varsayılan dilde belge gösterilir." } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/vi.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/vi.json new file mode 100644 index 0000000000..6f10e6469c --- /dev/null +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/vi.json @@ -0,0 +1,19 @@ +{ + "culture": "vi", + "texts": { + "Documents": "Tài liệu", + "BackToWebsite": "Quay lại trang web", + "Contributors": "Người đóng góp", + "ShareOn": "Chia sẻ", + "Version": "Phiên bản", + "Edit": "Sửa", + "Delete": "Xóa", + "InThisDocument": "Trong tài liệu này", + "GoToTop": "Chuyển về đầu trang", + "Projects": "Dự án", + "NoProjectWarning": "Chưa có dự án nào!", + "DocumentNotFound": "Rất tiếc, tài liệu được yêu cầu không tìm thấy!", + "NavigationDocumentNotFound": "Phiên bản này không có tài liệu điều hướng!", + "DocumentNotFoundInSelectedLanguage": "Tài liệu bằng ngôn ngữ bạn muốn không được tìm thấy. Tài liệu trong ngôn ngữ mặc định được hiển thị." + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json index f085265abf..43eb83334c 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json @@ -13,6 +13,7 @@ "Projects": "项目", "NoProjectWarning": "还没有项目!", "DocumentNotFound": "找不到请求的文档!", - "NavigationDocumentNotFound": "这个版本没有导航文件!" + "NavigationDocumentNotFound": "这个版本没有导航文件!", + "DocumentNotFoundInSelectedLanguage": "本文档不适用于所选语言, 将以默认语言显示文档." } -} +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs index 709614a230..edc7bfb24d 100644 --- a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs @@ -144,7 +144,7 @@ namespace Volo.Docs.Areas.Documents.TagHelpers var prefix = _urlOptions.GetFormattedRoutePrefix(); - return "/" + prefix + LanguageCode + "/" + ProjectName + "/" + Version + "/" + pathWithoutFileExtension; + return prefix + LanguageCode + "/" + ProjectName + "/" + Version + "/" + pathWithoutFileExtension; } private string RemoveFileExtensionFromPath(string path) diff --git a/modules/docs/src/Volo.Docs.Web/DocsUrlOptions.cs b/modules/docs/src/Volo.Docs.Web/DocsUrlOptions.cs index 283b343965..4c72a7bcbb 100644 --- a/modules/docs/src/Volo.Docs.Web/DocsUrlOptions.cs +++ b/modules/docs/src/Volo.Docs.Web/DocsUrlOptions.cs @@ -13,10 +13,10 @@ namespace Volo.Docs { if (string.IsNullOrWhiteSpace(RoutePrefix)) { - return ""; + return "/"; } - return RoutePrefix.Trim('/').EnsureEndsWith('/'); + return RoutePrefix.EnsureEndsWith('/').EnsureStartsWith('/'); } } } diff --git a/modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs b/modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs index 5bf88664ef..426a42d59d 100644 --- a/modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs +++ b/modules/docs/src/Volo.Docs.Web/Markdown/MarkdownDocumentToHtmlConverter.cs @@ -23,7 +23,7 @@ namespace Volo.Docs.Markdown _urlOptions = urlOptions.Value; } - private const string MdLinkFormat = "[{0}](/{1}{2}/{3}/{4}{5}/{6})"; + private const string MdLinkFormat = "[{0}]({1}{2}/{3}/{4}{5}/{6})"; private const string MarkdownLinkRegExp = @"\[(.*)\]\((.*\.md)\)"; private const string AnchorLinkRegExp = @"]+href=\""(.*?)\""[^>]*>(.*)?"; diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs index 186a9122db..25083571b4 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Index.cshtml.cs @@ -33,7 +33,7 @@ namespace Volo.Docs.Pages.Documents if (listResult.Items.Count == 1) { - return Redirect("./" + DocumentsUrlPrefix + listResult.Items[0].ShortName); + return Redirect("." + DocumentsUrlPrefix + listResult.Items[0].ShortName); } Projects = listResult.Items; diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index a7fc072011..6fd1a21797 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -192,8 +192,8 @@
@if (Model.DocumentLanguageIsDifferent) { - - Document in the language you wanted is not found. Document in the default language is shown. + + @L["DocumentNotFoundInSelectedLanguage"] } @Html.Raw(Model.Document.Content) diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs index 83a1f62f27..94fec82c09 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.Extensions.Options; +using Volo.Abp.AspNetCore.Mvc.Localization; using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Localization; using Volo.Docs.Documents; using Volo.Docs.HtmlConverting; using Volo.Docs.Models; @@ -72,6 +75,11 @@ namespace Volo.Docs.Pages.Documents.Project { DocumentsUrlPrefix = _options.GetFormattedRoutePrefix(); + if (IsDocumentCultureDifferentThanCurrent()) + { + return ReloadPageWithCulture(); + } + await SetProjectAsync(); await SetProjectsAsync(); await SetVersionAsync(); @@ -94,6 +102,24 @@ namespace Volo.Docs.Pages.Documents.Project return Page(); } + private bool IsDocumentCultureDifferentThanCurrent() + { + var currentCulture = CultureInfo.CurrentCulture; + CultureInfo newCulture; + + try + { + newCulture = CultureInfo.GetCultureInfo(LanguageCode); + + return currentCulture.Name != newCulture.Name; + } + catch (CultureNotFoundException) + { + return false; + } + + } + private bool IsDefaultDocument() { return DocumentName == Project.DefaultDocumentName; @@ -120,6 +146,14 @@ namespace Volo.Docs.Pages.Documents.Project return LanguageConfig.Languages.Any(l => l.Code == LanguageCode); } + private IActionResult ReloadPageWithCulture() + { + var returnUrl = DocumentsUrlPrefix + LanguageCode + "/" + ProjectName + "/" + Version + "/" + + DocumentName; + + return Redirect("/Abp/Languages/Switch?culture=" + LanguageCode + "&uiCulture=" + LanguageCode + "&returnUrl=" + returnUrl); + } + private IActionResult RedirectToDefaultLanguage() { return RedirectToPage(new @@ -317,7 +351,7 @@ namespace Volo.Docs.Pages.Documents.Project LanguageSelectListItems.Add( new SelectListItem( language.DisplayName, - "/" + DocumentsUrlPrefix + language.Code + "/" + Project.ShortName + "/" + Version + "/" + DocumentName, + DocumentsUrlPrefix + language.Code + "/" + Project.ShortName + "/" + Version + "/" + DocumentName, language.Code == LanguageCode ) ); diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/Localization/ApplicationContracts/pl.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/Localization/ApplicationContracts/pl.json new file mode 100644 index 0000000000..2ea227cbf3 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/Localization/ApplicationContracts/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + + } +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/Localization/ApplicationContracts/vi.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/Localization/ApplicationContracts/vi.json new file mode 100644 index 0000000000..d8eb5f3c75 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application.Contracts/Volo/Abp/FeatureManagement/Localization/ApplicationContracts/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/Localization/Domain/pl.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/Localization/Domain/pl.json new file mode 100644 index 0000000000..2ea227cbf3 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/Localization/Domain/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + + } +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/Localization/Domain/vi.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/Localization/Domain/vi.json new file mode 100644 index 0000000000..d8eb5f3c75 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain/Volo/Abp/FeatureManagement/Localization/Domain/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + + } +} diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Localization/Resources/FeatureManagement/pl.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Localization/Resources/FeatureManagement/pl.json new file mode 100644 index 0000000000..d714a0d499 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Localization/Resources/FeatureManagement/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + "Features": "Funkcje" + } +} \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Localization/Resources/FeatureManagement/vi.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Localization/Resources/FeatureManagement/vi.json new file mode 100644 index 0000000000..f8eda1da21 --- /dev/null +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Web/Localization/Resources/FeatureManagement/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + "Features": "Tính năng" + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Localization/ApplicationContracts/pl.json b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Localization/ApplicationContracts/pl.json new file mode 100644 index 0000000000..4ebaa0c660 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Localization/ApplicationContracts/pl.json @@ -0,0 +1,14 @@ +{ + "culture": "pl", + "texts": { + "Volo.Abp.Identity:010001": "Nie możesz usunąć swojego własnego konta!", + "Permission:IdentityManagement": "Zarządzanie tożsamością", + "Permission:RoleManagement": "Zarządanie rolami", + "Permission:Create": "Utwórz", + "Permission:Edit": "Edytuj", + "Permission:Delete": "Usuń", + "Permission:ChangePermissions": "Zmień uprawnienia", + "Permission:UserManagement": "Zarządzanie użytkownikami", + "Permission:UserLookup": "Wyszukiwanie użytkownika" + } +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Localization/ApplicationContracts/vi.json b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Localization/ApplicationContracts/vi.json new file mode 100644 index 0000000000..e9576d3ea9 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/Localization/ApplicationContracts/vi.json @@ -0,0 +1,14 @@ +{ + "culture": "vi", + "texts": { + "Volo.Abp.Identity:010001": "Bạn không thể xóa tài khoản của riêng bạn!", + "Permission:IdentityManagement": "Quản lý danh tính", + "Permission:RoleManagement": "Quản lý vai trò", + "Permission:Create": "Tạo", + "Permission:Edit": "Sửa", + "Permission:Delete": "Xóa", + "Permission:ChangePermissions": "Thay đổi quyền", + "Permission:UserManagement": "Quản lý người dùng", + "Permission:UserLookup": "Tra cứu người dùng" + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Localization/Domain/pl.json b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Localization/Domain/pl.json new file mode 100644 index 0000000000..7a1011ef96 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Localization/Domain/pl.json @@ -0,0 +1,33 @@ +{ + "culture": "pl", + "texts": { + "Identity.DefaultError": "Wystąpił niespodziewany błąd.", + "Identity.ConcurrencyFailure": "Optymistyczny błąd współbierzności, obiekt został zmodyfikowany.", + "Identity.DuplicateEmail": "Email '{0}' już istnieje.", + "Identity.DuplicateRoleName": "Rola '{0}' już istnieje.", + "Identity.DuplicateUserName": "Nazwa użytkownika '{0}' już istnieje.", + "Identity.InvalidEmail": "Email '{0}' jest niepoprawny.", + "Identity.InvalidPasswordHasherCompatibilityMode": "Dostawca PasswordHasherCompatibilityMode jest niepoprawny.", + "Identity.InvalidPasswordHasherIterationCount": "Wartość iteracji musi być większa od zera.", + "Identity.InvalidRoleName": "Rola '{0}' jest niepoprawna.", + "Identity.InvalidToken": "Niepoprawny token.", + "Identity.InvalidUserName": "Nazwa użytkownika '{0}' jest niepoprawna, może zawierać tylko litery i cyfry.", + "Identity.LoginAlreadyAssociated": "Użytkownik o tym loginie już istnieje.", + "Identity.PasswordMismatch": "Niepoprawne hasło.", + "Identity.PasswordRequiresDigit": "Hasło musi zawierać przynajmniej jedną cyfrę ('0'-'9').", + "Identity.PasswordRequiresLower": "Hasło musi zawierać przynajmniej jedną małą literę ('a'-'z').", + "Identity.PasswordRequiresNonAlphanumeric": "Hasło musi zawierać przynajmniej jeden znak alfanumeryczny.", + "Identity.PasswordRequiresUpper": "Hasło musi zawierać przynajmniej jedną wielką literę ('A'-'Z').", + "Identity.PasswordTooShort": "Hasło musi zawierać przynajmnie {0} znaków.", + "Identity.RoleNotFound": "Rola {0} nie istnieje.", + "Identity.UserAlreadyHasPassword": "Użytkownik ma już ustawione hasło.", + "Identity.UserAlreadyInRole": "Użytkownik jest już przypisany do roli '{0}'.", + "Identity.UserLockedOut": "Użytkownik jest zablokowany.", + "Identity.UserLockoutNotEnabled": "Blokada nie jest włączona dla tego użytkownika.", + "Identity.UserNameNotFound": "Użytkownik {0} nie istnieje.", + "Identity.UserNotInRole": "Użytkownik nie posiada roli '{0}'.", + "Identity.PasswordConfirmationFailed": "Podane hasła różnią się od siebie.", + "Identity.StaticRoleRenamingErrorMessage": "Statyczna rola nie może mieć zmienionej nazwy.", + "Identity.StaticRoleDeletionErrorMessage": "Statyczna rola nie może zostać usunięta." + } +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Localization/Domain/vi.json b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Localization/Domain/vi.json new file mode 100644 index 0000000000..7546865cfc --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/Localization/Domain/vi.json @@ -0,0 +1,33 @@ +{ + "culture": "vi", + "texts": { + "Identity.DefaultError": "Một thất bại chưa biết đã xảy ra.", + "Identity.ConcurrencyFailure": "Thất bại đồng thời lạc quan, đối tượng đã được sửa đổi.", + "Identity.DuplicateEmail": "Email '{0}' đã được sử dụng.", + "Identity.DuplicateRoleName": "Tên vài trò '{0}' đã được sử dụng.", + "Identity.DuplicateUserName": "User name '{0}' đã được sử dụng.", + "Identity.InvalidEmail": "Email '{0}' Không hợp lệ.", + "Identity.InvalidPasswordHasherCompatibilityMode": "PasswordHasherCompatibilityMode được cung cấp không hợp lệ.", + "Identity.InvalidPasswordHasherIterationCount": "Số lần lặp phải là số nguyên dương.", + "Identity.InvalidRoleName": "Tên người dùng '{0}' Không hợp lệ.", + "Identity.InvalidToken": "Token không hợp lệ.", + "Identity.InvalidUserName": "Tên người dùng '{0}' không hợp lệ, chỉ có thể chứa chữ cái hoặc chữ số.", + "Identity.LoginAlreadyAssociated": "Một người dùng có thông tin đăng nhập này đã tồn tại.", + "Identity.PasswordMismatch": "Mật khẩu không đúng.", + "Identity.PasswordRequiresDigit": "Mật khẩu phải có ít nhất một chữ số ('0'-'9').", + "Identity.PasswordRequiresLower": "Mật khẩu phải có ít nhất một chữ thường ('a'-'z').", + "Identity.PasswordRequiresNonAlphanumeric": "Mật khẩu phải có ít nhất một ký tự không phải là chữ và số.", + "Identity.PasswordRequiresUpper": "Mật khẩu phải có ít nhất một chữ hoa ('A'-'Z').", + "Identity.PasswordTooShort": "Mật khẩu phải ít nhất {0} kí tự.", + "Identity.RoleNotFound": "Vai trò {0} không tồn tại.", + "Identity.UserAlreadyHasPassword": "Người dùng đã có một mật khẩu.", + "Identity.UserAlreadyInRole": "Người dùng đã có vai trò '{0}'.", + "Identity.UserLockedOut": "Người dùng bị khóa.", + "Identity.UserLockoutNotEnabled": "Khóa không được kích hoạt cho người dùng này.", + "Identity.UserNameNotFound": "Người dùng {0} không tồn tại.", + "Identity.UserNotInRole": "Người dùng không có vai trò '{0}'.", + "Identity.PasswordConfirmationFailed": "Mật khẩu không khớp với mật khẩu xác nhận.", + "Identity.StaticRoleRenamingErrorMessage": "Vai trò này là cố định không được phép đổi tên.", + "Identity.StaticRoleDeletionErrorMessage": "Vai trò này là cố định không được phép xóa." + } +} diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/pl.json b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/pl.json new file mode 100644 index 0000000000..922e20b042 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/pl.json @@ -0,0 +1,39 @@ +{ + "culture": "pl", + "texts": { + "Menu:IdentityManagement": "Zarządzanie tożsamością", + "Users": "Użytkownicy", + "NewUser": "Nowy użytkownik", + "UserName": "Nazwa użytkownika", + "EmailAddress": "Adres email", + "PhoneNumber": "Numer telefonu", + "UserInformations": "Notyfikacje użytkownika", + "DisplayName:IsDefault": "Domyślny", + "DisplayName:IsStatic": "Statyczny", + "DisplayName:IsPublic": "Publiczny", + "Roles": "Role", + "Password": "Hasło", + "PersonalInfo": "Mój profil", + "PersonalSettings": "Ustawienia personalne", + "UserDeletionConfirmationMessage": "Użytkownik '{0}' zostanie usunięty. Czy na pewno?", + "RoleDeletionConfirmationMessage": "Rola '{0}' zostanie usunięta. Czy na pewno?", + "DisplayName:RoleName": "Nazwa roli", + "DisplayName:UserName": "Nazwa użytkownika", + "DisplayName:Name": "Imię", + "DisplayName:Surname": "Nazwisko", + "DisplayName:Password": "Hasło", + "DisplayName:Email": "Adres email", + "DisplayName:PhoneNumber": "Numer telefonu", + "DisplayName:TwoFactorEnabled": "Dwustopniowa weryfikacja", + "DisplayName:LockoutEnabled": "Blokowanie konta po nieudanych próbach zalogowania", + "NewRole": "Nowa rola", + "RoleName": "Nazwa roli", + "CreationTime": "Data utworzenia", + "Permissions": "Uprawnienia", + "DisplayName:CurrentPassword": "Aktualne hasło", + "DisplayName:NewPassword": "Nowe hasło", + "DisplayName:NewPasswordConfirm": "Powtierdź nowe hasło", + "PasswordChangedMessage": "Twoje hasło zostało zmienione pomyślnie.", + "PersonalSettingsSavedMessage": "Twoje personalne ustawienia zostały zapisane pomyślnie." + } +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/vi.json b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/vi.json new file mode 100644 index 0000000000..b43484b0c8 --- /dev/null +++ b/modules/identity/src/Volo.Abp.Identity.Web/Localization/Resources/AbpIdentity/vi.json @@ -0,0 +1,39 @@ +{ + "culture": "vi", + "texts": { + "Menu:IdentityManagement": "Quản lý danh tính", + "Users": "Người dùng", + "NewUser": "Tạo người dùng mới", + "UserName": "Tên đăng nhập", + "EmailAddress": "Địa chỉ email", + "PhoneNumber": "Số điện thoại", + "UserInformations": "Thông tin người dùng", + "DisplayName:IsDefault": "Mặc định", + "DisplayName:IsStatic": "Cố định", + "DisplayName:IsPublic": "Công khai", + "Roles": "Vai trò", + "Password": "Mật khẩu", + "PersonalInfo": "Thông tin của tôi", + "PersonalSettings": "Thiết lập cá nhân", + "UserDeletionConfirmationMessage": "Người '{0}' sẽ bị xóa. Bạn có xác nhận điều này không?", + "RoleDeletionConfirmationMessage": "vai trò '{0}' sẽ bị xóa. Bạn có xác nhận điều này không?", + "DisplayName:RoleName": "Tên vai trò", + "DisplayName:UserName": "Tên người dùng", + "DisplayName:Name": "Tên", + "DisplayName:Surname": "Họ", + "DisplayName:Password": "mật khẩu", + "DisplayName:Email": "Địa chỉ email", + "DisplayName:PhoneNumber": "Số điện thoại", + "DisplayName:TwoFactorEnabled": "Xác thực hai yếu tố", + "DisplayName:LockoutEnabled": "Khóa tài khoản sau những lần đăng nhập thất bại", + "NewRole": "Vai trò mới", + "RoleName": "Tên vai trò", + "CreationTime": "Thời gian tạo", + "Permissions": "Quyền", + "DisplayName:CurrentPassword": "Mật khẩu hiện tại", + "DisplayName:NewPassword": "Mật khẩu mới", + "DisplayName:NewPasswordConfirm": "Xác nhận mật khẩu", + "PasswordChangedMessage": "Mật khẩu của bạn đã được thay đổi thành công.", + "PersonalSettingsSavedMessage": "Thiết lập của bạn đã được lưu lại thành công." + } +} diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Localization/Resources/AbpPermissionManagement/pl.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Localization/Resources/AbpPermissionManagement/pl.json new file mode 100644 index 0000000000..e1043feea7 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Localization/Resources/AbpPermissionManagement/pl.json @@ -0,0 +1,10 @@ +{ + "culture": "pl", + "texts": { + "Permissions": "Uprawnienia", + "OnlyProviderPermissons": "Tylko ten dostawca", + "All": "Wszystkie", + "SelectAllInAllTabs": "Udziel wszystkich uprawnień", + "SelectAllInThisTab": "Zaznacz wszystkie" + } +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Localization/Resources/AbpPermissionManagement/vi.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Localization/Resources/AbpPermissionManagement/vi.json new file mode 100644 index 0000000000..9364bcf588 --- /dev/null +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Localization/Resources/AbpPermissionManagement/vi.json @@ -0,0 +1,10 @@ +{ + "culture": "vi", + "texts": { + "Permissions": "Quyền", + "OnlyProviderPermissons": "Chỉ nhà cung cấp này", + "All": "Tất cả", + "SelectAllInAllTabs": "Cấp tất cả các quyền", + "SelectAllInThisTab": "Chọn tất cả" + } +} diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Localization/Resources/AbpSettingManagement/pl.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Localization/Resources/AbpSettingManagement/pl.json new file mode 100644 index 0000000000..4aa474d82b --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Localization/Resources/AbpSettingManagement/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + "Settings": "Ustawienia" + } +} \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Localization/Resources/AbpSettingManagement/vi.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Localization/Resources/AbpSettingManagement/vi.json new file mode 100644 index 0000000000..9da742c377 --- /dev/null +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Web/Localization/Resources/AbpSettingManagement/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + "Settings": "Cài đặt" + } +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/Localization/ApplicationContracts/pl.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/Localization/ApplicationContracts/pl.json new file mode 100644 index 0000000000..500b784dfd --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/Localization/ApplicationContracts/pl.json @@ -0,0 +1,11 @@ +{ + "culture": "pl", + "texts": { + "Permission:TenantManagement": "Zarządzanie tenantami", + "Permission:Create": "Utwórz", + "Permission:Edit": "Edytuj", + "Permission:Delete": "Usuń", + "Permission:ManageConnectionStrings": "Zarządzaj connection string'ami", + "Permission:ManageFeatures": "Zarządzaj fukcjami" + } +} \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/Localization/ApplicationContracts/vi.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/Localization/ApplicationContracts/vi.json new file mode 100644 index 0000000000..3518883435 --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Application.Contracts/Volo/Abp/TenantManagement/Localization/ApplicationContracts/vi.json @@ -0,0 +1,11 @@ +{ + "culture": "vi", + "texts": { + "Permission:TenantManagement": "Quản lý khách thuê", + "Permission:Create": "Tạo", + "Permission:Edit": "Sửa", + "Permission:Delete": "Xóa", + "Permission:ManageConnectionStrings": "Quản lý chuỗi kết nối", + "Permission:ManageFeatures": "Quản lý các tính năng" + } +} diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Localization/Resources/AbpTenantManagement/Web/pl.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Localization/Resources/AbpTenantManagement/Web/pl.json new file mode 100644 index 0000000000..537d235293 --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Localization/Resources/AbpTenantManagement/Web/pl.json @@ -0,0 +1,14 @@ +{ + "culture": "pl", + "texts": { + "Menu:TenantManagement": "Zarządzanie tenantami", + "Tenants": "Tenanty", + "NewTenant": "Nowy tenant", + "TenantName": "Nazwa tenantu", + "DisplayName:TenantName": "Nazwa tenantu", + "TenantDeletionConfirmationMessage": "Tenant '{0}' zostanie usunięty. Czy na pewno?", + "ConnectionStrings": "Connection Strings", + "DisplayName:DefaultConnectionString": "Domyślny Connection String", + "DisplayName:UseSharedDatabase": "Użyj współdzielonej bazy danych" + } +} \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Localization/Resources/AbpTenantManagement/Web/vi.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Localization/Resources/AbpTenantManagement/Web/vi.json new file mode 100644 index 0000000000..1818cbdffd --- /dev/null +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Web/Localization/Resources/AbpTenantManagement/Web/vi.json @@ -0,0 +1,14 @@ +{ + "culture": "vi", + "texts": { + "Menu:TenantManagement": "Quản lý người thuê", + "Tenants": "Người thuê", + "NewTenant": "Người thuê mới", + "TenantName": "Tên người thuê", + "DisplayName:TenantName": "Tên người thuê", + "TenantDeletionConfirmationMessage": "Người thuê '{0}' sẽ bị xóa. Bạn có xác nhận không?", + "ConnectionStrings": "Chuỗi kết nối", + "DisplayName:DefaultConnectionString": "Chuỗi kết nối mặc định", + "DisplayName:UseSharedDatabase": "Sử dụng cơ sở dữ liệu dùng chung" + } +} diff --git a/npm/packs/aspnetcore.mvc.ui.theme.shared/package.json b/npm/packs/aspnetcore.mvc.ui.theme.shared/package.json index e8fdce70e0..08f41e55e2 100644 --- a/npm/packs/aspnetcore.mvc.ui.theme.shared/package.json +++ b/npm/packs/aspnetcore.mvc.ui.theme.shared/package.json @@ -15,7 +15,8 @@ "@abp/select2": "^0.4.9", "@abp/sweetalert": "^0.4.9", "@abp/timeago": "^0.4.9", - "@abp/toastr": "^0.4.9" + "@abp/toastr": "^0.4.9", + "@abp/freeze-ui": "^0.5.3" }, "gitHead": "2e846ad3e5a8cbe04100484865335fbcd845a342" } diff --git a/npm/packs/freeze-ui/abp.resourcemapping.js b/npm/packs/freeze-ui/abp.resourcemapping.js new file mode 100644 index 0000000000..b027f07c88 --- /dev/null +++ b/npm/packs/freeze-ui/abp.resourcemapping.js @@ -0,0 +1,6 @@ +module.exports = { + mappings: { + "@node_modules/@abp/freeze-ui/lib/freeze-ui.min.js": "@libs/freeze-ui/", + "@node_modules/@abp/freeze-ui/lib/freeze-ui.min.css": "@libs/freeze-ui/" + } +} \ No newline at end of file diff --git a/npm/packs/freeze-ui/lib/freeze-ui.min.css b/npm/packs/freeze-ui/lib/freeze-ui.min.css new file mode 100644 index 0000000000..0f85b42513 --- /dev/null +++ b/npm/packs/freeze-ui/lib/freeze-ui.min.css @@ -0,0 +1 @@ +@keyframes spin{0%{transform:translateZ(0) rotate(0)}100%{transform:translateZ(0) rotate(360deg)}}.freeze-ui{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999999999;background-color:#fff;opacity:.8;transition:opacity .25s}.freeze-ui.is-unfreezing{opacity:0}.freeze-ui:after{content:attr(data-text);display:block;max-width:125px;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:20px;font-family:sans-serif;color:#343a40;text-align:center;text-transform:uppercase}.freeze-ui:before{content:"";display:block;width:150px;height:150px;border-radius:50%;border-width:2px;border-style:solid;border-color:transparent #228ae6 #228ae6;position:absolute;top:calc(50% - 75px);left:calc(50% - 75px);will-change:transform;animation:spin .75s infinite ease-in-out} \ No newline at end of file diff --git a/npm/packs/freeze-ui/lib/freeze-ui.min.js b/npm/packs/freeze-ui/lib/freeze-ui.min.js new file mode 100644 index 0000000000..991416917c --- /dev/null +++ b/npm/packs/freeze-ui/lib/freeze-ui.min.js @@ -0,0 +1 @@ +(()=>{let a=document.createElement('div');a.classList.add('freeze-ui'),window.FreezeUI=(b={})=>{let c=document.querySelector(b.selector)||document.body;a.setAttribute('data-text',b.text||'Loading'),document.querySelector(b.selector)&&(a.style.position='absolute'),c.appendChild(a)},window.UnFreezeUI=()=>{let b=document.querySelector('.freeze-ui');b&&(b.classList.add('is-unfreezing'),setTimeout(()=>{b&&(b.classList.remove('is-unfreezing'),b.parentElement.removeChild(b))},250))}})(); \ No newline at end of file diff --git a/npm/packs/freeze-ui/package.json b/npm/packs/freeze-ui/package.json new file mode 100644 index 0000000000..0a150676c1 --- /dev/null +++ b/npm/packs/freeze-ui/package.json @@ -0,0 +1,11 @@ +{ + "version": "0.5.3", + "name": "@abp/freeze-ui", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@abp/core": "^0.5.3" + }, + "gitHead": "824de4c615c1d4d1d7f07d6ec1e8d0cb3a303c72" +} diff --git a/samples/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/pl.json b/samples/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/pl.json new file mode 100644 index 0000000000..a018dc2126 --- /dev/null +++ b/samples/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/pl.json @@ -0,0 +1,20 @@ +{ + "culture": "pl", + "texts": { + "Menu:Home": "Home", + "Welcome": "Witaj", + "LongWelcomeMessage": "Witaj w aplikacji. To jest inicjalny projekt bazujący na ABP framework. Po więcej informacji odwiedź stronę abp.io.", + "Menu:BookStore": "Sklep z ksiąkami", + "Menu:Books": "Ksiąki", + "Name": "Nazwa", + "Type": "Typ", + "PublishDate": "Data publikacji", + "Price": "Cena", + "CreationTime": "Data utworzenia", + "NewBook": "Nowa ksiąka", + "Books": "Ksiąki", + "Update": "Aktualizuj", + "BookDeletionConfirmationMessage": "Czy jesteś pewien, że chcesz usunąć {0}?", + "SuccessfullyDeleted": "Usunięto pomyślnie." + } +} \ No newline at end of file diff --git a/samples/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/vi.json b/samples/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/vi.json new file mode 100644 index 0000000000..3aad66a64a --- /dev/null +++ b/samples/BookStore/src/Acme.BookStore.Domain.Shared/Localization/BookStore/vi.json @@ -0,0 +1,20 @@ +{ + "culture": "vi", + "texts": { + "Menu:Home": "Trang chủ", + "Welcome": "Chào mừng bạn", + "LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là một dự án mẫu dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io.", + "Menu:BookStore": "Cửa hàng sách", + "Menu:Books": "Sách", + "Name": "Tên", + "Type": "Loại", + "PublishDate": "Ngày xuất bản", + "Price": "Giá", + "CreationTime": "Thời gian tạo", + "NewBook": "Sách mới", + "Books": "Sách", + "Update": "Cập nhật", + "BookDeletionConfirmationMessage": "Bạn có chắc chắn xóa sách {0}?", + "SuccessfullyDeleted": "Xóa thành công." + } +} diff --git a/samples/DashboardDemo/src/DashboardDemo.Domain/Localization/DashboardDemo/pl.json b/samples/DashboardDemo/src/DashboardDemo.Domain/Localization/DashboardDemo/pl.json new file mode 100644 index 0000000000..f1a26b3f9f --- /dev/null +++ b/samples/DashboardDemo/src/DashboardDemo.Domain/Localization/DashboardDemo/pl.json @@ -0,0 +1,10 @@ +{ + "culture": "pl", + "texts": { + "Menu:Home": "Home", + "Welcome": "Witaj", + "RolesInApplication": "Role w aplikacji", + "UserCount": "Ilość użytkowników", + "LongWelcomeMessage": "Witaj w aplikacji. To jest inicjalny projekt bazujący na ABP framework. Po więcej informacji odwiedź stronę abp.io." + } +} \ No newline at end of file diff --git a/samples/DashboardDemo/src/DashboardDemo.Domain/Localization/DashboardDemo/vi.json b/samples/DashboardDemo/src/DashboardDemo.Domain/Localization/DashboardDemo/vi.json new file mode 100644 index 0000000000..c629274a1b --- /dev/null +++ b/samples/DashboardDemo/src/DashboardDemo.Domain/Localization/DashboardDemo/vi.json @@ -0,0 +1,10 @@ +{ + "culture": "vi", + "texts": { + "Menu:Home": "Trang chủ", + "Welcome": "Xin chào bạn", + "RolesInApplication": "Vai trò trong ứng dụng", + "UserCount": "Số lượng người dùng", + "LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là mẫu khởi động dự án dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io." + } +} diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/pl.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/pl.json new file mode 100644 index 0000000000..9181e35186 --- /dev/null +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/pl.json @@ -0,0 +1,10 @@ +{ + "culture": "pl", + "texts": { + "Permission:ProductManagement": "Zarządzanie produktami", + "Permission:Products": "Produkty", + "Permission:Edit": "Edytuj", + "Permission:Delete": "Usuń", + "Permission:Create": "Utwórz" + } +} \ No newline at end of file diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/vi.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/vi.json new file mode 100644 index 0000000000..97cca61fd2 --- /dev/null +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Application.Contracts/ProductManagement/Localization/ApplicationContracts/vi.json @@ -0,0 +1,10 @@ +{ + "culture": "vi", + "texts": { + "Permission:ProductManagement": "Quản lý sản phẩm", + "Permission:Products": "Sản phẩm", + "Permission:Edit": "Sửa", + "Permission:Delete": "Xóa", + "Permission:Create": "Tạo" + } +} diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/pl.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/pl.json new file mode 100644 index 0000000000..2ea227cbf3 --- /dev/null +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + + } +} \ No newline at end of file diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/vi b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/vi new file mode 100644 index 0000000000..d8eb5f3c75 --- /dev/null +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/vi @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + + } +} diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/vi.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/vi.json new file mode 100644 index 0000000000..d8eb5f3c75 --- /dev/null +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Domain/ProductManagement/Localization/Domain/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + + } +} diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/pl.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/pl.json new file mode 100644 index 0000000000..5828dd8942 --- /dev/null +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/pl.json @@ -0,0 +1,16 @@ +{ + "culture": "pl", + "texts": { + "Menu:ProductManagement": "Zarządzanie produktami", + "Menu:Products": "Produkty", + "ProductManagement": "Zarządzanie produktami", + "CreateANewProduct": "Utwórz nowy produkt", + "Products": "Produkty", + "StockCount": "Ilość na magazynie", + "Code": "Kod", + "Name": "Nazwa", + "Price": "Cena", + "ImageName": "Nazwa obrazka", + "ProductDeletionWarningMessage": "Czy jesteś pewien, że chcesz usunąć ten produkt?" + } +} \ No newline at end of file diff --git a/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/vi.json b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/vi.json new file mode 100644 index 0000000000..6b51506813 --- /dev/null +++ b/samples/MicroserviceDemo/modules/product/src/ProductManagement.Web/Localization/Resources/ProductManagement/vi.json @@ -0,0 +1,16 @@ +{ + "culture": "vi", + "texts": { + "Menu:ProductManagement": "Quản lý sản phẩm", + "Menu:Products": "Sản phẩm", + "ProductManagement": "Quản lý sản phẩm", + "CreateANewProduct": "Tạo một sản phẩm mới", + "Products": "Sản phẩm", + "StockCount": "Số chứng khoán", + "Code": "Mã", + "Name": "Tên", + "Price": "Giá", + "ImageName": "Tên ảnh", + "ProductDeletionWarningMessage": "Bạn có chắc chắn muốn xóa sản phẩm này?" + } +} diff --git a/templates/mvc-module/MyCompanyName.MyProjectName.sln b/templates/mvc-module/MyCompanyName.MyProjectName.sln index 9ca4ac6631..ea7d59fe2c 100644 --- a/templates/mvc-module/MyCompanyName.MyProjectName.sln +++ b/templates/mvc-module/MyCompanyName.MyProjectName.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27703.2026 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29001.49 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName.Domain.Shared", "src\MyCompanyName.MyProjectName.Domain.Shared\MyCompanyName.MyProjectName.Domain.Shared.csproj", "{D64C1577-4929-4B60-939E-96DE1534891A}" EndProject @@ -13,7 +13,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{649A3FFA-182F-4E56-9717-E6A9A2BEC545}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{CCD2960C-23CC-4AB4-B84D-60C7AAA52F4D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "host", "host", "{E400416D-2895-4512-9D17-90681EEC7E0A}" EndProject diff --git a/templates/mvc-module/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj b/templates/mvc-module/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj index 9e51bd05cf..d6436852b6 100644 --- a/templates/mvc-module/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj +++ b/templates/mvc-module/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj @@ -14,7 +14,7 @@ - + diff --git a/templates/mvc-module/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj b/templates/mvc-module/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj index b1d532024c..cdf7bcb65e 100644 --- a/templates/mvc-module/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj +++ b/templates/mvc-module/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj @@ -12,7 +12,7 @@ - + diff --git a/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj b/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj index 8a5fb3e236..dd7ba84dbd 100644 --- a/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj +++ b/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj @@ -14,7 +14,7 @@ - + diff --git a/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostModule.cs b/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostModule.cs index 8cbb8fa01a..ea15dd040b 100644 --- a/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostModule.cs +++ b/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebHostModule.cs @@ -150,8 +150,6 @@ namespace MyCompanyName.MyProjectName { Configure(options => { - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); // options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); @@ -161,6 +159,9 @@ namespace MyCompanyName.MyProjectName options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}modules{0}permission-management{0}src{0}Volo.Abp.PermissionManagement.Web", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}modules{0}identity{0}src{0}Volo.Abp.Identity.Web", Path.DirectorySeparatorChar))); // + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Web", Path.DirectorySeparatorChar))); }); } } diff --git a/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs b/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs index 85e77ff406..76ae5ef988 100644 --- a/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs +++ b/templates/mvc-module/host/MyCompanyName.MyProjectName.Web.Unified/MyProjectNameWebUnifiedModule.cs @@ -69,10 +69,10 @@ namespace MyCompanyName.MyProjectName { Configure(options => { - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Domain.Shared", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Application", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Application", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}src{0}MyCompanyName.MyProjectName.Web", Path.DirectorySeparatorChar))); }); } diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Application.Contracts/Localization/MyProjectName/ApplicationContracts/pl.json b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application.Contracts/Localization/MyProjectName/ApplicationContracts/pl.json new file mode 100644 index 0000000000..3b93a2b580 --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application.Contracts/Localization/MyProjectName/ApplicationContracts/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + "Permission:MyProjectName": "MyProjectName" + } +} \ No newline at end of file diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Application.Contracts/Localization/MyProjectName/ApplicationContracts/vi.json b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application.Contracts/Localization/MyProjectName/ApplicationContracts/vi.json new file mode 100644 index 0000000000..a60afc038e --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application.Contracts/Localization/MyProjectName/ApplicationContracts/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + "Permission:MyProjectName": "TenDuAnCuaBan" + } +} diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppServiceBase.cs b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppService.cs similarity index 65% rename from templates/mvc-module/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppServiceBase.cs rename to templates/mvc-module/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppService.cs index e54468cb79..31bfbeb0de 100644 --- a/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppServiceBase.cs +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppService.cs @@ -3,9 +3,9 @@ using Volo.Abp.Application.Services; namespace MyCompanyName.MyProjectName { - public abstract class MyProjectNameAppServiceBase : ApplicationService + public abstract class MyProjectNameAppService : ApplicationService { - protected MyProjectNameAppServiceBase() + protected MyProjectNameAppService() { LocalizationResource = typeof(MyProjectNameResource); } diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/Samples/SampleAppService.cs b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/Samples/SampleAppService.cs index d193c3f895..f34b7771bd 100644 --- a/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/Samples/SampleAppService.cs +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Application/Samples/SampleAppService.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Authorization; namespace MyCompanyName.MyProjectName.Samples { - public class SampleAppService : MyProjectNameAppServiceBase, ISampleAppService + public class SampleAppService : MyProjectNameAppService, ISampleAppService { public Task GetAsync() { diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/DomainShared/pl.json b/templates/mvc-module/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/DomainShared/pl.json new file mode 100644 index 0000000000..2ea227cbf3 --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/DomainShared/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + + } +} \ No newline at end of file diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/DomainShared/vi.json b/templates/mvc-module/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/DomainShared/vi.json new file mode 100644 index 0000000000..d8eb5f3c75 --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/DomainShared/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + + } +} diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameControllerBase.cs b/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameController.cs similarity index 66% rename from templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameControllerBase.cs rename to templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameController.cs index f447b65456..1dd9a6c8b2 100644 --- a/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameControllerBase.cs +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/MyProjectNameController.cs @@ -3,9 +3,9 @@ using Volo.Abp.AspNetCore.Mvc; namespace MyCompanyName.MyProjectName { - public class MyProjectNameControllerBase : AbpController + public abstract class MyProjectNameController : AbpController { - public MyProjectNameControllerBase() + protected MyProjectNameController() { LocalizationResource = typeof(MyProjectNameResource); } diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/Samples/SampleController.cs b/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/Samples/SampleController.cs index 7c4de3b65e..1bf34c32c4 100644 --- a/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/Samples/SampleController.cs +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.HttpApi/Samples/SampleController.cs @@ -7,7 +7,7 @@ namespace MyCompanyName.MyProjectName.Samples { [RemoteService] [Route("api/MyProjectName/sample")] - public class SampleController : MyProjectNameControllerBase, ISampleAppService + public class SampleController : MyProjectNameController, ISampleAppService { private readonly ISampleAppService _sampleAppService; diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Localization/MyProjectName/Web/pl.json b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Localization/MyProjectName/Web/pl.json new file mode 100644 index 0000000000..2ea227cbf3 --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Localization/MyProjectName/Web/pl.json @@ -0,0 +1,6 @@ +{ + "culture": "pl", + "texts": { + + } +} \ No newline at end of file diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Localization/MyProjectName/Web/vi.json b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Localization/MyProjectName/Web/vi.json new file mode 100644 index 0000000000..d8eb5f3c75 --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Localization/MyProjectName/Web/vi.json @@ -0,0 +1,6 @@ +{ + "culture": "vi", + "texts": { + + } +} diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectName/Index.cshtml b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectName/Index.cshtml new file mode 100644 index 0000000000..0ef7562269 --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectName/Index.cshtml @@ -0,0 +1,7 @@ +@page +@inherits MyCompanyName.MyProjectName.Web.Pages.MyProjectNamePage +@model MyCompanyName.MyProjectName.Web.Pages.MyProjectName.IndexModel +@{ +} +

MyProjectName

+

A sample page for the MyProjectName module.

\ No newline at end of file diff --git a/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectName/Index.cshtml.cs b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectName/Index.cshtml.cs new file mode 100644 index 0000000000..a9c43a1c88 --- /dev/null +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectName/Index.cshtml.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace MyCompanyName.MyProjectName.Web.Pages.MyProjectName +{ + public class IndexModel : PageModel + { + public void OnGet() + { + } + } +} \ No newline at end of file diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageBase.cs b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePage.cs similarity index 56% rename from templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageBase.cs rename to templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePage.cs index 217c70d491..5fe044221d 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageBase.cs +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePage.cs @@ -5,7 +5,10 @@ using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; namespace MyCompanyName.MyProjectName.Web.Pages { - public abstract class MyProjectNamePageBase : AbpPage + /* Inherit your UI Pages from this class. To do that, add this line to your Pages (.cshtml files under the Page folder): + * @inherits MyCompanyName.MyProjectName.Web.Pages.MyProjectNamePage + */ + public abstract class MyProjectNamePage : AbpPage { [RazorInject] public IHtmlLocalizer L { get; set; } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModelBase.cs b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModel.cs similarity index 59% rename from templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModelBase.cs rename to templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModel.cs index afd22b08c4..d0b9c04a45 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModelBase.cs +++ b/templates/mvc-module/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModel.cs @@ -3,9 +3,11 @@ using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; namespace MyCompanyName.MyProjectName.Web.Pages { - public abstract class MyProjectNamePageModelBase : AbpPageModel + /* Inherit your PageModel classes from this class. + */ + public abstract class MyProjectNamePageModel : AbpPageModel { - protected MyProjectNamePageModelBase() + protected MyProjectNamePageModel() { LocalizationResourceType = typeof(MyProjectNameResource); } diff --git a/templates/mvc-module/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj b/templates/mvc-module/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj index bfefdfcbfd..22898fcde0 100644 --- a/templates/mvc-module/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj +++ b/templates/mvc-module/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/templates/mvc-module/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj b/templates/mvc-module/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj index 68328a77a1..2b2fd34bea 100644 --- a/templates/mvc-module/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj +++ b/templates/mvc-module/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/templates/mvc-module/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj b/templates/mvc-module/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj index 7a05b65e55..3b0c247ddf 100644 --- a/templates/mvc-module/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj +++ b/templates/mvc-module/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/templates/mvc-module/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj b/templates/mvc-module/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj index e71954d6a3..8ddb93bfdc 100644 --- a/templates/mvc-module/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj +++ b/templates/mvc-module/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/templates/mvc-module/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj b/templates/mvc-module/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj index 1481ea0ad4..4e2b8b1ed4 100644 --- a/templates/mvc-module/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj +++ b/templates/mvc-module/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj @@ -8,7 +8,7 @@ - + diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppService.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppService.cs new file mode 100644 index 0000000000..8cf7cca603 --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Application/MyProjectNameAppService.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MyCompanyName.MyProjectName.Localization; +using Volo.Abp.Application.Services; + +namespace MyCompanyName.MyProjectName +{ + /* Inherit your application services from this class. + */ + public abstract class MyProjectNameAppService : ApplicationService + { + protected MyProjectNameAppService() + { + LocalizationResource = typeof(MyProjectNameResource); + } + } +} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/pl.json b/templates/mvc/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/pl.json new file mode 100644 index 0000000000..815bbcc83f --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/pl.json @@ -0,0 +1,8 @@ +{ + "culture": "pl", + "texts": { + "Menu:Home": "Home", + "Welcome": "Witaj", + "LongWelcomeMessage": "Witaj w aplikacji. To jest inicjalny projekt bazujący na ABP framework. Po więcej informacji odwiedź stronę abp.io." + } +} \ No newline at end of file diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/vi.json b/templates/mvc/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/vi.json new file mode 100644 index 0000000000..c115a35726 --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/vi.json @@ -0,0 +1,8 @@ +{ + "culture": "vi", + "texts": { + "Menu:Home": "Trang chủ", + "Welcome": "Chào mừng bạn", + "LongWelcomeMessage": "Chào mừng bạn đến ứng dụng. Đây là một dự án khởi nghiệp dựa trên khung ABP. Để biết thêm thông tin, hãy truy cập abp.io." + } +} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj index e719e8aeb5..d68c13bc6b 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj @@ -15,7 +15,7 @@ - + diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs index c80e008681..7fff0ecbc5 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.HttpApi/Controllers/MyProjectNameController.cs @@ -3,6 +3,8 @@ using Volo.Abp.AspNetCore.Mvc; namespace MyCompanyName.MyProjectName.Controllers { + /* Inherit your controllers from this class. + */ public abstract class MyProjectNameController : AbpController { protected MyProjectNameController() diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj b/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj index cd21488394..8c18d8a43e 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj +++ b/templates/mvc/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj @@ -26,7 +26,7 @@ - + diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj b/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj index 8390830f55..4d9d970ace 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj @@ -20,7 +20,7 @@ - + diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs index 7eba8ff7c8..17df5f5df5 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web.Host/MyProjectNameWebModule.cs @@ -145,8 +145,6 @@ namespace MyCompanyName.MyProjectName.Web { Configure(options => { - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); // options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); @@ -156,6 +154,9 @@ namespace MyCompanyName.MyProjectName.Web options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}modules{0}permission-management{0}src{0}Volo.Abp.PermissionManagement.Web", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}modules{0}identity{0}src{0}Volo.Abp.Identity.Web", Path.DirectorySeparatorChar))); // + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(hostingEnvironment.ContentRootPath); }); } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs index 84cacf1d48..77da95f24a 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web/MyProjectNameWebModule.cs @@ -113,11 +113,6 @@ namespace MyCompanyName.MyProjectName.Web { Configure(options => { - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Domain.Shared", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Application", Path.DirectorySeparatorChar))); - options.FileSets.ReplaceEmbeddedByPhysical(hostingEnvironment.ContentRootPath); // options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.UI", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}framework{0}src{0}Volo.Abp.AspNetCore.Mvc.UI", Path.DirectorySeparatorChar))); @@ -128,6 +123,11 @@ namespace MyCompanyName.MyProjectName.Web options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}modules{0}identity{0}src{0}Volo.Abp.Identity.Web", Path.DirectorySeparatorChar))); options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}..{0}..{0}..{0}modules{0}account{0}src{0}Volo.Abp.Account.Web", Path.DirectorySeparatorChar))); // + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Domain.Shared", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Domain", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Application.Contracts", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(Path.Combine(hostingEnvironment.ContentRootPath, string.Format("..{0}MyCompanyName.MyProjectName.Application", Path.DirectorySeparatorChar))); + options.FileSets.ReplaceEmbeddedByPhysical(hostingEnvironment.ContentRootPath); }); } } diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml index 2565dc8267..9324a9891a 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml @@ -1,5 +1,5 @@ @page -@inherits MyCompanyName.MyProjectName.Web.Pages.MyProjectNamePageBase +@inherits MyCompanyName.MyProjectName.Web.Pages.MyProjectNamePage @model MyCompanyName.MyProjectName.Web.Pages.IndexModel @section styles { diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml.cs index f8d2476c5b..6a89e42f63 100644 --- a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml.cs +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/Index.cshtml.cs @@ -1,6 +1,6 @@ namespace MyCompanyName.MyProjectName.Web.Pages { - public class IndexModel : MyProjectNamePageModelBase + public class IndexModel : MyProjectNamePageModel { public void OnGet() { diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePage.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePage.cs new file mode 100644 index 0000000000..5fe044221d --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePage.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Mvc.Localization; +using Microsoft.AspNetCore.Mvc.Razor.Internal; +using MyCompanyName.MyProjectName.Localization; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace MyCompanyName.MyProjectName.Web.Pages +{ + /* Inherit your UI Pages from this class. To do that, add this line to your Pages (.cshtml files under the Page folder): + * @inherits MyCompanyName.MyProjectName.Web.Pages.MyProjectNamePage + */ + public abstract class MyProjectNamePage : AbpPage + { + [RazorInject] + public IHtmlLocalizer L { get; set; } + } +} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModel.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModel.cs new file mode 100644 index 0000000000..d0b9c04a45 --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Web/Pages/MyProjectNamePageModel.cs @@ -0,0 +1,15 @@ +using MyCompanyName.MyProjectName.Localization; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace MyCompanyName.MyProjectName.Web.Pages +{ + /* Inherit your PageModel classes from this class. + */ + public abstract class MyProjectNamePageModel : AbpPageModel + { + protected MyProjectNamePageModel() + { + LocalizationResourceType = typeof(MyProjectNameResource); + } + } +} \ No newline at end of file diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj index a6f18a84b2..a9845fe4b3 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj index 0cc541e353..24e65fa533 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj index 46e07869da..6b5a5e757c 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj index 0ae2555849..7fba41965c 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj index 37db2e4cbd..1b0f53db9c 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/Security/FakeCurrentPrincipalAccessor.cs b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/Security/FakeCurrentPrincipalAccessor.cs new file mode 100644 index 0000000000..ef00c20a24 --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/Security/FakeCurrentPrincipalAccessor.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.Security.Claims; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Security.Claims; + +namespace MyCompanyName.MyProjectName.Security +{ + [Dependency(ReplaceServices = true)] + public class FakeCurrentPrincipalAccessor : ICurrentPrincipalAccessor, ISingletonDependency + { + public ClaimsPrincipal Principal => GetPrincipal(); + private ClaimsPrincipal _principal; + + private ClaimsPrincipal GetPrincipal() + { + if (_principal == null) + { + lock (this) + { + if (_principal == null) + { + _principal = new ClaimsPrincipal( + new ClaimsIdentity( + new List + { + new Claim(AbpClaimTypes.UserId,"2e701e62-0953-4dd3-910b-dc6cc93ccb0d"), + new Claim(AbpClaimTypes.UserName,"admin"), + new Claim(AbpClaimTypes.Email,"admin@abp.io") + } + ) + ); + } + } + } + + return _principal; + } + } +} \ No newline at end of file diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj index 1f93e615d3..f3b0d21c93 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj @@ -14,7 +14,7 @@ - +