diff --git a/docs/docs-langs.json b/docs/docs-langs.json index d4ee0190d2..a73882bd51 100644 --- a/docs/docs-langs.json +++ b/docs/docs-langs.json @@ -4,6 +4,11 @@ "DisplayName" : "English", "Code" : "en", "IsDefault": true + }, + { + "DisplayName" : "Português", + "Code" : "pt-BR", + "IsDefault": false }, { "DisplayName" : "简体中文", diff --git a/docs/pt-BR/Contribution/Index.md b/docs/pt-BR/Contribution/Index.md new file mode 100644 index 0000000000..e51ff4646c --- /dev/null +++ b/docs/pt-BR/Contribution/Index.md @@ -0,0 +1,60 @@ +## Guia de Contribuição + +O ABP é um projeto de [código aberto](https://github.com/abpframework) e orientado à comunidade. Este guia tem como objetivo ajudar alguém que queira contribuir com o projeto. + +### Contribuição de código + +Você sempre pode enviar solicitações pull ao repositório do Github. + +- Clone o [repositório ABP](https://github.com/abpframework/abp/) do Github. +- Faça as alterações necessárias. +- Envie uma solicitação de recebimento. + +Antes de fazer qualquer alteração, discuta-a sobre os [problemas](https://github.com/abpframework/abp/issues) do [Github](https://github.com/abpframework/abp/issues) . Dessa forma, nenhum outro desenvolvedor trabalhará no mesmo problema e seu PR terá uma chance melhor de ser aceito. + +#### Correções de bugs e aprimoramentos + +Você pode corrigir um bug conhecido ou trabalhar em uma melhoria planejada. Veja [a lista de problemas](https://github.com/abpframework/abp/issues) no Github. + +#### Solicitações de recursos + +Se você tem uma ideia de recurso para a estrutura ou módulos, [crie um problema](https://github.com/abpframework/abp/issues/new) no Github ou participe de uma discussão existente. Então você pode implementá-lo se for adotado pela comunidade. + +### Tradução de documentos + +Você pode traduzir a [documentação](https://abp.io/documents/) completa (incluindo esta) para o idioma materno. Nesse caso, siga estas etapas: + +- Clone o [repositório ABP](https://github.com/abpframework/abp/) do Github. +- Para adicionar um novo idioma, crie uma nova pasta dentro da pasta [docs](https://github.com/abpframework/abp/tree/master/docs) . Os nomes das pastas podem ser "en", "es", "fr", "tr" e assim por diante, com base no idioma (consulte [todos os códigos de cultura](https://msdn.microsoft.com/en-us/library/hh441729.aspx) ). +- Obtenha a [pasta "en"](https://github.com/abpframework/abp/tree/master/docs/en) como uma referência para os nomes de arquivos e a estrutura de pastas. Mantenha o mesmo nome se estiver traduzindo a mesma documentação. +- Envie uma solicitação de recebimento (PR) depois de traduzir qualquer documento. Traduza documentos e envie PRs um por um. Não espere para terminar as traduções de todos os documentos. + +Alguns documentos fundamentais precisam ser traduzidos antes da publicação de um idioma no [site de documentação](https://docs.abp.io/) da [ABP](https://docs.abp.io/) : + +- Documentos de introdução +- Tutoriais +- CLI + +Um novo idioma é publicado após a conclusão dessas traduções mínimas. + +### Localização de Recursos + +A estrutura ABP possui um [sistema de localização](../Localization.md) flexível . Você pode criar interfaces de usuário localizadas para seu próprio aplicativo. + +Além disso, os módulos de estrutura e pré-construção já localizaram textos. Como exemplo, veja [os textos de localização para o pacote Volo.Abp.UI](https://github.com/abpframework/abp/blob/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi/en.json) . Você pode criar um novo arquivo na [mesma pasta](https://github.com/abpframework/abp/tree/master/framework/src/Volo.Abp.UI/Localization/Resources/AbpUi) para traduzi-lo. + +- Clone o [repositório ABP](https://github.com/abpframework/abp/) do Github. +- Crie um novo arquivo para o idioma de destino para um arquivo de texto de localização (json) (próximo ao arquivo en.json). +- Copie todos os textos do arquivo en.json. +- Traduzir os textos. +- Enviar solicitação de recebimento no Github. + +ABP é uma estrutura modular. Portanto, existem muitos recursos de texto de localização, um por módulo. Para encontrar todos os arquivos .json, você pode procurar por "en.json" após clonar o repositório. Você também pode verificar [esta lista](https://docs.abp.io/en/abp/latest/Contribution/Localization-Text-Files) para obter uma lista de arquivos de texto de localização. + +### Posts e tutoriais do blog + +Se você decidir criar alguns tutoriais ou postagens de blog no ABP, informe-nos (criando um [problema no Github](https://github.com/abpframework/abp/issues) ), para que possamos adicionar um link ao seu tutorial / publicação na documentação oficial e podemos anunciá-lo em nossa [conta do Twitter](https://twitter.com/abpframework) . + +### Relatório de erro + +Se você encontrar algum erro, [crie um problema no repositório do Github](https://github.com/abpframework/abp/issues/new) . \ No newline at end of file diff --git a/docs/pt-BR/Getting-Started-Angular-Template.md b/docs/pt-BR/Getting-Started-Angular-Template.md new file mode 100644 index 0000000000..cc08b63917 --- /dev/null +++ b/docs/pt-BR/Getting-Started-Angular-Template.md @@ -0,0 +1,126 @@ +## Introdução ao modelo de aplicativo angular + +Este tutorial explica como criar um novo aplicativo Angular usando o modelo de inicialização, configurar e executá-lo. + +### Criando um novo projeto + +Este tutorial usa o **ABP CLI** para criar um novo projeto. Consulte a página [Introdução](https://abp.io/get-started) para outras opções. + +Instale a CLI ABP usando uma janela de linha de comando, se você não tiver instalado antes: + +```bash +dotnet tool install -g Volo.Abp.Cli +``` + +Use o `abp new`comando em uma pasta vazia para criar seu projeto: + +```bash +abp new Acme.BookStore -u angular +``` + +> Você pode usar diferentes níveis de namespaces; por exemplo, BookStore, Acme.BookStore ou Acme.Retail.BookStore. + +`-u angular`A opção especifica que a estrutura da interface do usuário seja Angular. O provedor de banco de dados padrão é o EF Core. Consulte a [documentação](CLI.md) da [CLI](CLI.md) para todas as opções disponíveis. + +#### Pré requisitos + +A solução criada requer; + +- [Visual Studio 2017 (v15.9.0 +)](https://visualstudio.microsoft.com/tr/downloads/) +- [.NET Core 2.2 ou superior](https://www.microsoft.com/net/download/dotnet-core/) +- [Node v10.16 +](https://nodejs.org/) +- [Yarn v1.17 +](https://yarnpkg.com/) + +### A Estrutura da Solução + +Abra a solução no **Visual Studio** : + +![livraria-visual-studio-solução](images/bookstore-visual-studio-solution-for-spa.png) + +A solução possui uma estrutura em camadas (baseada no [Domain Driven Design](Domain-Driven-Design.md) ) e contém projetos de teste de unidade e integração adequadamente configurados para trabalhar com o **banco de** dados de **memória** **EF Core** e **SQLite** . + +> Consulte o [documento do modelo do aplicativo](Startup-Templates/Application.md) para entender a estrutura da solução em detalhes. + +### Cadeia de Conexão de Banco de Dados + +Verifique a **cadeia de conexão** no `appsettings.json`arquivo no `.HttpApi.Host`projeto: + +```json +{ + "ConnectionStrings": { + "Default": "Server=localhost;Database=BookStore;Trusted_Connection=True" + } +} +``` + +A solução está configurada para usar o **Entity Framework Core** com o **MS SQL Server** . O EF Core suporta [vários](https://docs.microsoft.com/en-us/ef/core/providers/) provedores de banco de dados, para que você possa usar outro DBMS, se desejar. Mude a cadeia de conexão, se necessário. + +### Criar banco de dados e aplicar migrações de banco de dados + +Você tem duas opções para criar o banco de dados. + +#### Usando o aplicativo DbMigrator + +A solução contém um aplicativo de console (nomeado `Acme.BookStore.DbMigrator`nesta amostra) que pode criar banco de dados, aplicar migrações e propagar dados iniciais. É útil no desenvolvimento e no ambiente de produção. + +> `.DbMigrator`projeto tem o seu próprio `appsettings.json`. Portanto, se você alterou a cadeia de conexão acima, também deve alterar esta. + +Clique com o botão direito do mouse no `.DbMigrator`projeto e selecione **Definir como Projeto de Inicialização** : + +![definir como projeto de inicialização](images/set-as-startup-project.png) + +Pressione F5 (ou Ctrl + F5) para executar o aplicativo. Terá uma saída como mostrado abaixo: + +![definir como projeto de inicialização](images/db-migrator-app.png) + +#### Usando o comando EF Core Update-Database + +O Ef Core possui um `Update-Database`comando que cria banco de dados, se necessário, e aplica migrações pendentes. Clique com o botão direito do mouse no `.Web`projeto e selecione **Definir como Projeto de Inicialização** : + +![definir como projeto de inicialização](images/set-as-startup-project.png) + +Abra o **Console do Gerenciador de Pacotes** , selecione o `.EntityFrameworkCore.DbMigrations`projeto como **Projeto Padrão** e execute o `Update-Database`comando: + +![pcm-update-database](images/pcm-update-database-v2.png) + +Isso criará um novo banco de dados com base na cadeia de conexão configurada. + +> O uso da `.Migrator`ferramenta é a maneira sugerida, porque também semeia os dados iniciais para poder executar corretamente o aplicativo Web. + +### Executando o aplicativo + +#### Execute o host da API (lado do servidor) + +Verifique se o `.HttpApi.Host`projeto é o projeto de inicialização e o aplicativo que abrirá uma interface do usuário do Swagger: + +![livraria-homepage](images/bookstore-swagger-ui-host.png) + +Você pode ver as APIs do aplicativo e testá-las aqui. Obtenha [mais informações](https://swagger.io/tools/swagger-ui/) sobre a interface do usuário do Swagger. + +##### Autorização para a interface do usuário do Swagger + +A maioria das APIs de aplicativos requer autenticação e autorização. Se você deseja testar APIs autorizadas, vá manualmente para a `/Account/Login`página, digite `admin`como o nome de usuário e `1q2w3E*`a senha para efetuar login no aplicativo. Você também poderá executar APIs autorizadas. + +#### Execute o aplicativo angular (lado do cliente) + +Vá para a `angular`pasta, abra um terminal de linha de comando, digite o `yarn`comando (sugerimos ao gerenciador de pacotes do [yarn](https://yarnpkg.com/) enquanto o npm install também funcionará na maioria dos casos): + +```bash +yarn +``` + +Depois que todos os módulos do nó estiverem carregados, execute `yarn start`ou `npm start`comando: + +```bash +yarn start +``` + +Abra seu navegador favorito e vá para `localhost:4200`URL. Nome de usuário inicial é `admin`e senha é `1q2w3E*`. + +O modelo de inicialização inclui os módulos de **gerenciamento de** **identidade** e **gerenciamento de inquilino** . Após o login, o menu Administração estará disponível, onde você poderá gerenciar **inquilinos** , **funções** , **usuários** e suas **permissões** . + +> Recomendamos o [Visual Studio Code](https://code.visualstudio.com/) como editor do projeto Angular, mas você pode usar seu editor favorito. + +### Qual é o próximo? + +- [Tutorial de desenvolvimento de aplicativos](Tutorials/Angular/Part-I.md) \ No newline at end of file diff --git a/docs/pt-BR/Getting-Started-AspNetCore-Application.md b/docs/pt-BR/Getting-Started-AspNetCore-Application.md new file mode 100644 index 0000000000..b7f5b793be --- /dev/null +++ b/docs/pt-BR/Getting-Started-AspNetCore-Application.md @@ -0,0 +1,183 @@ +# Introdução ao ABP com o aplicativo Web MVC AspNet Core + +Este tutorial explica como iniciar o ABP do zero com dependências mínimas. Você geralmente deseja começar com o **modelo de inicialização** . + +## Criar um novo projeto + +1. Crie um novo aplicativo da Web vazio do AspNet Core no Visual Studio: + +![img](images/create-new-aspnet-core-application.png) + +1. Selecionar modelo vazio + +![img](images/select-empty-web-application.png) + +Você pode selecionar outro modelo, mas quero mostrá-lo em um projeto claro. + +## Instale o pacote Volo.Abp.AspNetCore.Mvc + +Volo.Abp.AspNetCore.Mvc é um pacote de integração do AspNet Core MVC para ABP. Então, instale-o no seu projeto: + +``` +Install-Package Volo.Abp.AspNetCore.Mvc +``` + +## Criar o primeiro módulo ABP + +O ABP é uma estrutura modular e requer uma classe de **módulo de inicialização (raiz)** derivada de `AbpModule`: + +```csharp +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.AspNetCore.Modularity; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; + +namespace BasicAspNetCoreApplication +{ + [DependsOn(typeof(AbpAspNetCoreMvcModule))] + public class AppModule : AbpModule + { + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseMvcWithDefaultRoute(); + } + } +} +``` + +`AppModule` é um bom nome para o módulo de inicialização de um aplicativo. + +Os pacotes ABP definem as classes do módulo e um módulo pode depender de outro módulo. No código acima, nosso `AppModule`depende `AbpAspNetCoreMvcModule`(definido pelo pacote Volo.Abp.AspNetCore.Mvc). É comum adicionar um `DependsOn`atributo após a instalação de um novo pacote de nuget ABP. + +Em vez da classe Startup, estamos configurando o pipeline do ASP.NET Core nesta classe de módulo. + +## A classe de inicialização + +O próximo passo é modificar a classe Startup para integrar ao sistema do módulo ABP: + +```csharp +using System; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace BasicAspNetCoreApplication +{ + public class Startup + { + public IServiceProvider ConfigureServices(IServiceCollection services) + { + services.AddApplication(); + + return services.BuildServiceProviderFromFactory(); + } + + public void Configure(IApplicationBuilder app) + { + app.InitializeApplication(); + } + } +} +``` + +`ConfigureServices`Método alterado para retornar em `IServiceProvider`vez de `void`. Essa alteração nos permite substituir a injeção de dependência do AspNet Core por outra estrutura (consulte a seção de integração com Autofac abaixo). `services.AddApplication()`adiciona todos os serviços definidos em todos os módulos a partir do `AppModule`. + +`app.InitializeApplication()`O `Configure`método call in inicializa e inicia o aplicativo. + +## Olá Mundo! + +O aplicativo acima não faz nada. Vamos criar um controlador MVC que faz algo: + +```csharp +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace BasicAspNetCoreApplication.Controllers +{ + public class HomeController : AbpController + { + public IActionResult Index() + { + return Content("Hello World!"); + } + } +} +``` + +Se você executar o aplicativo, verá um "Olá, mundo!" mensagem na página. + +Derivado `HomeController`de em `AbpController`vez de `Controller`classe padrão . Isso não é necessário, mas a `AbpController`classe possui propriedades e métodos base úteis para facilitar seu desenvolvimento. + +## Usando Autofac como a estrutura de injeção de dependência + +Embora o sistema de Injeção de Dependência (DI) do AspNet Core seja adequado para requisitos básicos, o Autofac fornece recursos avançados, como Injeção de Propriedade e Interceptação de Método, exigidos pela ABP para executar recursos avançados da estrutura de aplicativos. + +Substituir o sistema DI do AspNet Core pelo Autofac e integrar ao ABP é bastante fácil. + +1. Instale o pacote [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) + +``` +Install-Package Volo.Abp.Autofac +``` + +1. Adicionar `AbpAutofacModule`dependência + +```csharp +[DependsOn(typeof(AbpAspNetCoreMvcModule))] +[DependsOn(typeof(AbpAutofacModule))] //Add dependency to ABP Autofac module +public class AppModule : AbpModule +{ + ... +} +``` + +1. Altere a `services.AddApplication();`linha na `Startup`classe, como mostrado abaixo: + +```csharp +services.AddApplication(options => +{ + options.UseAutofac(); //Integrate to Autofac +}); +``` + +1. Atualize `Program.cs`para não usar o `WebHost.CreateDefaultBuilder()`método, pois ele usa o contêiner DI padrão: + +```csharp +public class Program +{ + public static void Main(string[] args) + { + /* + https://github.com/aspnet/AspNetCore/issues/4206#issuecomment-445612167 + CurrentDirectoryHelpers exists in: \framework\src\Volo.Abp.AspNetCore.Mvc\Microsoft\AspNetCore\InProcess\CurrentDirectoryHelpers.cs + Will remove CurrentDirectoryHelpers.cs when upgrade to ASP.NET Core 3.0. + */ + CurrentDirectoryHelpers.SetCurrentDirectory(); + + BuildWebHostInternal(args).Run(); + } + + public static IWebHost BuildWebHostInternal(string[] args) => + new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIIS() + .UseIISIntegration() + .UseStartup() + .Build(); +} +``` + +## Código fonte + +Obter código-fonte do projeto de exemplo criada neste tutorial a partir de [aqui](https://github.com/abpframework/abp/tree/master/samples/BasicAspNetCoreApplication) . \ No newline at end of file diff --git a/docs/pt-BR/Getting-Started-AspNetCore-MVC-Template.md b/docs/pt-BR/Getting-Started-AspNetCore-MVC-Template.md new file mode 100644 index 0000000000..076fd978ca --- /dev/null +++ b/docs/pt-BR/Getting-Started-AspNetCore-MVC-Template.md @@ -0,0 +1,102 @@ +## Introdução ao modelo ASP.NET Core MVC + +Este tutorial explica como criar um novo aplicativo Web ASP.NET Core MVC usando o modelo de inicialização, configurá-lo e executá-lo. + +### Criando um novo projeto + +Este tutorial usa o **ABP CLI** para criar um novo projeto. Consulte a página [Introdução](https://abp.io/get-started) para outras opções. + +Instale a CLI ABP usando uma janela de linha de comando, se você não tiver instalado antes: + +```bash +dotnet tool install -g Volo.Abp.Cli +``` + +Use o `abp new`comando em uma pasta vazia para criar seu projeto: + +```bash +abp new Acme.BookStore +``` + +> Você pode usar diferentes níveis de namespaces; por exemplo, BookStore, Acme.BookStore ou Acme.Retail.BookStore. + +`new`O comando cria um **aplicativo MVC em camadas** com o **Entity Framework Core** como o provedor de banco de dados. No entanto, possui opções adicionais. Consulte a [documentação](CLI.md) da [CLI](CLI.md) para todas as opções disponíveis. + +#### Pré requisitos + +A solução criada requer; + +- [Visual Studio 2017 (v15.9.0 +)](https://visualstudio.microsoft.com/tr/downloads/) +- [.NET Core 2.2 ou superior](https://www.microsoft.com/net/download/dotnet-core/) + +### A Estrutura da Solução + +Abra a solução no **Visual Studio** : + +![livraria-visual-studio-solução](images/bookstore-visual-studio-solution-v3.png) + +A solução possui uma estrutura em camadas (baseada no [Domain Driven Design](Domain-Driven-Design.md) ) e contém projetos de teste de unidade e integração adequadamente configurados para trabalhar com o **banco de** dados de **memória** **EF Core** e **SQLite** . + +> Consulte o [documento do modelo de aplicativo](Startup-Templates/Application.md) para entender a estrutura da solução em detalhes. + +### Cadeia de Conexão de Banco de Dados + +Verifique a **cadeia de conexão** no `appsettings.json`arquivo no `.Web`projeto: + +```json +{ + "ConnectionStrings": { + "Default": "Server=localhost;Database=BookStore;Trusted_Connection=True" + } +} +``` + +A solução está configurada para usar o **Entity Framework Core** com o **MS SQL Server** . O EF Core suporta [vários](https://docs.microsoft.com/en-us/ef/core/providers/) provedores de banco de dados, para que você possa usar outro DBMS, se desejar. Mude a cadeia de conexão, se necessário. + +### Criar banco de dados e aplicar migrações de banco de dados + +Você tem duas opções para criar o banco de dados. + +#### Usando o aplicativo DbMigrator + +A solução contém um aplicativo de console (nomeado `Acme.BookStore.DbMigrator`nesta amostra) que pode criar banco de dados, aplicar migrações e propagar dados iniciais. É útil no desenvolvimento e no ambiente de produção. + +> `.DbMigrator`projeto tem o seu próprio `appsettings.json`. Portanto, se você alterou a cadeia de conexão acima, também deve alterar esta. + +Clique com o botão direito do mouse no `.DbMigrator`projeto e selecione **Definir como Projeto de Inicialização** : + +![definir como projeto de inicialização](images/set-as-startup-project.png) + +Pressione F5 (ou Ctrl + F5) para executar o aplicativo. Terá uma saída como mostrado abaixo: + +![definir como projeto de inicialização](images/db-migrator-app.png) + +#### Usando o comando EF Core Update-Database + +O Ef Core possui um `Update-Database`comando que cria banco de dados, se necessário, e aplica migrações pendentes. Clique com o botão direito do mouse no `.Web`projeto e selecione **Definir como Projeto de Inicialização** : + +![definir como projeto de inicialização](images/set-as-startup-project.png) + +Abra o **Console do Gerenciador de Pacotes** , selecione o `.EntityFrameworkCore.DbMigrations`projeto como **Projeto Padrão** e execute o `Update-Database`comando: + +![pcm-update-database](images/pcm-update-database-v2.png) + +Isso criará um novo banco de dados com base na cadeia de conexão configurada. + +> O uso da `.Migrator`ferramenta é a maneira sugerida, porque também semeia os dados iniciais para poder executar corretamente o aplicativo Web. + +### Executando o aplicativo + +Verifique se o `.Web`projeto é o projeto de inicialização. Execute o aplicativo que abrirá a página **inicial** no seu navegador: + +![livraria-homepage](images/bookstore-homepage.png) + +Clique no botão **Login** , insira `admin`como nome de usuário e `1q2w3E*`senha para acessar o aplicativo. + +O modelo de inicialização inclui os módulos de **gerenciamento de** **identidade** e **gerenciamento de inquilino** . Após o login, o menu Administração estará disponível, onde você poderá gerenciar **inquilinos** , **funções** , **usuários** e suas **permissões** . A página de gerenciamento de usuários é mostrada abaixo: + +![livraria-gerenciamento de usuários](images/bookstore-user-management-v2.png) + +### Qual é o próximo? + +- [Tutorial de desenvolvimento de aplicativos](Tutorials/AspNetCore-Mvc/Part-I.md) \ No newline at end of file diff --git a/docs/pt-BR/Getting-Started-Console-Application.md b/docs/pt-BR/Getting-Started-Console-Application.md new file mode 100644 index 0000000000..f21a959a9c --- /dev/null +++ b/docs/pt-BR/Getting-Started-Console-Application.md @@ -0,0 +1,182 @@ +# Introdução ao ABP com aplicativo de console + +Este tutorial explica como iniciar o ABP do zero com dependências mínimas. Você geralmente deseja começar com um **modelo de inicialização** . + +## Criar um novo projeto + +Crie um novo aplicativo regular .Net Core Console do Visual Studio: + +![img](images/create-new-net-core-console-application.png) + +## Instale o pacote Volo.Abp + +Volo.Abp.Core é o pacote principal de pepitas para criar aplicativos baseados em ABP. Então, instale-o no seu projeto: + +``` +Install-Package Volo.Abp.Core +``` + +## Criar o primeiro módulo ABP + +O ABP é uma estrutura modular e requer uma classe de **módulo de inicialização (raiz)** derivada de `AbpModule`: + +```csharp +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; + +namespace AbpConsoleDemo +{ + public class AppModule : AbpModule + { + + } +} +``` + +`AppModule` é um bom nome para o módulo de inicialização de um aplicativo. + +## Inicializar o aplicativo + +A próxima etapa é inicializar o aplicativo usando o módulo de inicialização criado acima: + +```csharp +using System; +using Volo.Abp; + +namespace AbpConsoleDemo +{ + class Program + { + static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create()) + { + application.Initialize(); + + Console.WriteLine("Press ENTER to stop application..."); + Console.ReadLine(); + } + } + } +} +``` + +`AbpApplicationFactory`é usado para criar o aplicativo e carregar todos os módulos que tomam `AppModule`como módulo de inicialização. `Initialize()`O método inicia o aplicativo. + +## Olá Mundo! + +O aplicativo acima não faz nada. Vamos criar um serviço que faça algo: + +```csharp +using System; +using Volo.Abp.DependencyInjection; + +namespace AbpConsoleDemo +{ + public class HelloWorldService : ITransientDependency + { + public void SayHello() + { + Console.WriteLine("Hello World!"); + } + } +} +``` + +`ITransientDependency`é uma interface especial do ABP que registra automaticamente o serviço como transitório (consulte o [documento de injeção de dependência](Dependency-Injection.md) ). + +Agora, podemos resolver o problema `HelloWorldService`e dizer olá. Altere o Program.cs como mostrado abaixo: + +```csharp +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace AbpConsoleDemo +{ + class Program + { + static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create()) + { + application.Initialize(); + + //Resolve a service and use it + var helloWorldService = + application.ServiceProvider.GetService(); + helloWorldService.SayHello(); + + Console.WriteLine("Press ENTER to stop application..."); + Console.ReadLine(); + } + } + } +} +``` + +Embora seja suficiente para este exemplo de código simples, é sempre recomendável criar escopos no caso de resolver diretamente dependências de `IServiceProvider`(consulte a [documentação de Injeção de Dependências](Dependency-Injection.md)). + +## Usando Autofac como a estrutura de injeção de dependência + +Embora o sistema de Injeção de Dependência (DI) do AspNet Core seja adequado para requisitos básicos, o Autofac fornece recursos avançados, como Injeção de Propriedade e Interceptação de Método, exigidos pela ABP para executar recursos avançados da estrutura de aplicativos. + +Substituir o sistema DI do AspNet Core pelo Autofac e integrar ao ABP é bastante fácil. + +1. Instale o pacote [Volo.Abp.Autofac](https://www.nuget.org/packages/Volo.Abp.Autofac) + +``` +Install-Package Volo.Abp.Autofac +``` + +1. Adicionar `AbpAutofacModule`dependência + +```csharp +[DependsOn(typeof(AbpAutofacModule))] //Add dependency to the AbpAutofacModule +public class AppModule : AbpModule +{ + +} +``` + +1. Mude o `Program.cs`arquivo como mostrado abaixo: + +```csharp +using System; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; + +namespace AbpConsoleDemo +{ + class Program + { + static void Main(string[] args) + { + using (var application = AbpApplicationFactory.Create(options => + { + options.UseAutofac(); //Autofac integration + })) + { + application.Initialize(); + + //Resolve a service and use it + var helloWorldService = + application.ServiceProvider.GetService(); + helloWorldService.SayHello(); + + Console.WriteLine("Press ENTER to stop application..."); + Console.ReadLine(); + } + } + } +} +``` + +Apenas chamado `options.UseAutofac()`método nas `AbpApplicationFactory.Create`opções. + +## Código fonte + +Obter código-fonte do projeto de exemplo criada neste tutorial a partir de [aqui](https://github.com/abpframework/abp/tree/master/samples/BasicConsoleApplication) . + + + \ No newline at end of file diff --git a/docs/pt-BR/Index.md b/docs/pt-BR/Index.md new file mode 100644 index 0000000000..c0a65e122c --- /dev/null +++ b/docs/pt-BR/Index.md @@ -0,0 +1,31 @@ +# Documentação ABP + +O ABP é uma **estrutura de aplicativos de código aberto** focada no desenvolvimento de aplicativos da Web baseado no ASP.NET Core, mas também suporta o desenvolvimento de outros tipos de aplicativos. + +Explore o menu de navegação esquerdo para mergulhar fundo na documentação. + +## Status do projeto + +ABP é a **próxima geração** da estrutura de código aberto [ASP.NET Boilerplate](https://aspnetboilerplate.com/) . Atualmente, está em fase de visualização e não está pronto para uso na produção. A documentação ainda está em andamento e está longe de estar completa. + +Para aplicativos de curto prazo e em nível de produção, é sugerido o uso da estrutura do [ASP.NET Boilerplate](https://aspnetboilerplate.com/) , que possui um rico conjunto de recursos, maduro, mantido ativamente e atualizado. + +## Começando + +A maneira mais fácil de iniciar um novo projeto com o ABP é usar os modelos de inicialização: + +- [Modelo de interface do usuário do ASP.NET Core MVC (Razor Pages)](Getting-Started-AspNetCore-MVC-Template.md) +- [Modelo de interface do usuário angular](Getting-Started-Angular-Template.md) + +Se você deseja começar do zero (com um projeto vazio), instale manualmente o ABP Framework e use os seguintes tutoriais: + +- [Aplicação de console](Getting-Started-Console-Application.md) +- [Aplicativo da Web principal do ASP.NET](Getting-Started-AspNetCore-Application.md) + +## Código fonte + +ABP está hospedado no GitHub. Veja [o código fonte](https://github.com/abpframework/abp) . + +## Deseja contribuir? + +O ABP é um projeto de código aberto orientado pela comunidade. Consulte [o guia de contribuição](Contribution/Index.md) se você quiser fazer parte deste projeto. \ No newline at end of file diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-I.md b/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-I.md new file mode 100644 index 0000000000..798836ba52 --- /dev/null +++ b/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-I.md @@ -0,0 +1,462 @@ +## Tutorial do ASP.NET Core MVC - Parte I + +### Sobre este tutorial + +Nesta série de tutoriais, você criará um aplicativo usado para gerenciar uma lista de livros e seus autores. **O Entity Framework Core** (EF Core) será usado como o provedor ORM, pois é o provedor de banco de dados padrão. + +Esta é a primeira parte da série de tutoriais do ASP.NET Core MVC. Veja todas as peças: + +- **Parte I: Crie o projeto e uma página de lista de livros (este tutorial)** +- [Parte II: Criar, atualizar e excluir livros](Part-II.md) +- [Parte III: Testes de Integração](Part-III.md) + +Você pode acessar o **código fonte** do aplicativo [no repositório GitHub](https://github.com/abpframework/abp/tree/master/samples/BookStore) . + +> Você também pode assistir a [este curso em vídeo](https://amazingsolutions.teachable.com/p/lets-build-the-bookstore-application) preparado por um membro da comunidade ABP, com base neste tutorial. + +### Criando o projeto + +Crie um novo projeto chamado `Acme.BookStore`, crie o banco de dados e execute o aplicativo seguindo o [documento Introdução](Getting-Started-AspNetCore-MVC-Template.md). + +### Estrutura da solução + +É assim que a estrutura da solução em camadas cuida da criação: + +![livraria-visual-studio-solução](images/bookstore-visual-studio-solution-v3.png) + +> Você pode ver o [documento do modelo de aplicativo](https://docs.abp.io/en/abp/latest/Startup-Templates/Application) para entender a estrutura da solução em detalhes. No entanto, você entenderá o básico com este tutorial. + +### Criar a entidade do livro + +A camada de domínio no modelo de inicialização é separada em dois projetos: + +- `Acme.BookStore.Domain`contém suas [entidades](https://docs.abp.io/en/abp/latest/Entities.md) , [serviços de domínio](https://docs.abp.io/en/abp/latest/Domain-Services) e outros objetos principais de domínio. +- `Acme.BookStore.Domain.Shared` contém constantes, enumerações ou outros objetos relacionados ao domínio que podem ser compartilhados com os clientes. + +Defina [entidades](https://docs.abp.io/en/abp/latest/Entities) na **camada de domínio** ( `Acme.BookStore.Domain`projeto) da solução. A entidade principal do aplicativo é a `Book`. Crie uma classe, chamada `Book`, no `Acme.BookStore.Domain`projeto, como mostrado abaixo: + +```csharp +using System; +using Volo.Abp.Domain.Entities.Auditing; + +namespace Acme.BookStore +{ + public class Book : AuditedAggregateRoot + { + public string Name { get; set; } + + public BookType Type { get; set; } + + public DateTime PublishDate { get; set; } + + public float Price { get; set; } + } +} +``` + +- O ABP possui duas classes base fundamentais para entidades: `AggregateRoot`e `Entity`. **A raiz agregada** é um dos conceitos de **DDD (Domain Driven Design)** . Consulte o [documento da entidade](https://docs.abp.io/en/abp/latest/Entities) para obter detalhes e melhores práticas. +- `Book`entidade herda `AuditedAggregateRoot`que adiciona algumas propriedades de auditoria ( `CreationTime`, `CreatorId`, `LastModificationTime`... etc.) no topo da `AggregateRoot`classe. +- `Guid`é o **tipo** de **chave primária** da `Book`entidade. + +#### BookType Enum + +Defina a `BookType`enumeração no `Acme.BookStore.Domain.Shared`projeto: + +```csharp +namespace Acme.BookStore +{ + public enum BookType + { + Undefined, + Adventure, + Biography, + Dystopia, + Fantastic, + Horror, + Science, + ScienceFiction, + Poetry + } +} +``` + +#### Adicionar entidade de livro ao seu DbContext + +O EF Core exige que você relacione entidades com seu DbContext. A maneira mais fácil de fazer isso é adicionar uma `DbSet`propriedade à `BookStoreDbContext`classe no `Acme.BookStore.EntityFrameworkCore`projeto, conforme mostrado abaixo: + +```csharp + public class BookStoreDbContext : AbpDbContext + { + public DbSet Books { get; set; } + ... + } +``` + +#### Configure sua entidade do livro + +Abra o `BookStoreDbContextModelCreatingExtensions.cs`arquivo no `Acme.BookStore.EntityFrameworkCore`projeto e adicione o seguinte código ao final do `ConfigureBookStore`método para configurar a entidade Livro: + +```csharp +builder.Entity(b => +{ + b.ToTable(BookStoreConsts.DbTablePrefix + "Books", BookStoreConsts.DbSchema); + b.ConfigureByConvention(); //auto configure for the base class props + b.Property(x => x.Name).IsRequired().HasMaxLength(128); +}); +``` + +#### Adicionar nova migração e atualizar o banco de dados + +O modelo de inicialização usa [as primeiras migrações do código principal EF](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/) para criar e manter o esquema do banco de dados. Abra o **Gerenciador de Console Package (PMC)** (sob as *Ferramentas / Gerente Nuget Package* menu), selecione o `Acme.BookStore.EntityFrameworkCore.DbMigrations`como o **projeto padrão** e execute o seguinte comando: + +![livraria-pmc-add-book-migration](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png) + +Isso criará uma nova classe de migração dentro da `Migrations`pasta. Em seguida, execute o `Update-Database`comando para atualizar o esquema do banco de dados: + +``` +PM> Update-Database +``` + +#### Adicionar dados de amostra + +`Update-Database`O comando criou a `AppBooks`tabela no banco de dados. Abra seu banco de dados e insira algumas linhas de amostra, para que você possa mostrá-las na página: + +![livraria-livros-mesa](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png) + +### Crie o serviço de aplicativo + +O próximo passo é criar um [serviço de aplicativo](https://docs.abp.io/en/abp/latest/Application-Services) para gerenciar (criar, listar, atualizar, excluir ...) os livros. A camada de aplicativo no modelo de inicialização é separada em dois projetos: + +- `Acme.BookStore.Application.Contracts` contém principalmente seus DTOs e interfaces de serviço de aplicativo. +- `Acme.BookStore.Application` contém as implementações dos seus serviços de aplicativo. + +#### BookDto + +Crie uma classe DTO denominada `BookDto`no `Acme.BookStore.Application.Contracts`projeto: + +```csharp +using System; +using Volo.Abp.Application.Dtos; + +namespace Acme.BookStore +{ + public class BookDto : AuditedEntityDto + { + public string Name { get; set; } + + public BookType Type { get; set; } + + public DateTime PublishDate { get; set; } + + public float Price { get; set; } + } +} +``` + +- **As** classes **DTO** são usadas para **transferir dados** entre a *camada de apresentação* e a *camada de aplicativo* . Consulte o [documento Objetos de transferência de dados](https://docs.abp.io/en/abp/latest/Data-Transfer-Objects) para obter mais detalhes. +- `BookDto` é usado para transferir dados do livro para a camada de apresentação para mostrar as informações do livro na interface do usuário. +- `BookDto`é derivado do `AuditedEntityDto`que possui propriedades de auditoria exatamente como a `Book`classe definida acima. + +Será necessário converter `Book`entidades em `BookDto`objetos enquanto retorna os livros para a camada de apresentação. [A](https://automapper.org/) biblioteca do [AutoMapper](https://automapper.org/) pode automatizar essa conversão quando você define o mapeamento adequado. O modelo de inicialização é fornecido com o AutoMapper configurado, para que você possa definir o mapeamento na `BookStoreApplicationAutoMapperProfile`classe no `Acme.BookStore.Application`projeto: + +```csharp +using AutoMapper; + +namespace Acme.BookStore +{ + public class BookStoreApplicationAutoMapperProfile : Profile + { + public BookStoreApplicationAutoMapperProfile() + { + CreateMap(); + } + } +} +``` + +#### CreateUpdateBookDto + +Crie uma classe DTO denominada `CreateUpdateBookDto`no `Acme.BookStore.Application.Contracts`projeto: + +```csharp +using System; +using System.ComponentModel.DataAnnotations; + +namespace Acme.BookStore +{ + public class CreateUpdateBookDto + { + [Required] + [StringLength(128)] + public string Name { get; set; } + + [Required] + public BookType Type { get; set; } = BookType.Undefined; + + [Required] + public DateTime PublishDate { get; set; } + + [Required] + public float Price { get; set; } + } +} +``` + +- Essa classe DTO é usada para obter informações do livro a partir da interface do usuário ao criar ou atualizar um livro. +- Ele define atributos de anotação de dados (como `[Required]`) para definir validações para as propriedades. Os DTOs são [validados automaticamente](https://docs.abp.io/en/abp/latest/Validation) pela estrutura ABP. + +Em seguida, adicione um mapeamento `BookStoreApplicationAutoMapperProfile`do `CreateUpdateBookDto`objeto à `Book`entidade: + +```csharp +CreateMap(); +``` + +#### IBookAppService + +Defina uma interface nomeada `IBookAppService`no `Acme.BookStore.Application.Contracts`projeto: + +```csharp +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace Acme.BookStore +{ + public interface IBookAppService : + ICrudAppService< //Defines CRUD methods + BookDto, //Used to show books + Guid, //Primary key of the book entity + PagedAndSortedResultRequestDto, //Used for paging/sorting on getting a list of books + CreateUpdateBookDto, //Used to create a new book + CreateUpdateBookDto> //Used to update a book + { + + } +} +``` + +- A definição de interfaces para serviços de aplicativos não é requerida pela estrutura. No entanto, é sugerido como uma prática recomendada. +- `ICrudAppService`define comuns **CRUD** métodos: `GetAsync`, `GetListAsync`, `CreateAsync`, `UpdateAsync`e `DeleteAsync`. Não é necessário estendê-lo. Em vez disso, você pode herdar da `IApplicationService`interface vazia e definir seus próprios métodos manualmente. +- Existem algumas variações de `ICrudAppService`onde você pode usar DTOs separados para cada método. + +#### BookAppService + +Implemente `IBookAppService`como nomeado `BookAppService`no `Acme.BookStore.Application`projeto: + +```csharp +using System; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Domain.Repositories; + +namespace Acme.BookStore +{ + public class BookAppService : + CrudAppService, + IBookAppService + { + public BookAppService(IRepository repository) + : base(repository) + { + + } + } +} +``` + +- `BookAppService`é derivado do `CrudAppService<...>`qual implementa todos os métodos CRUD definidos acima. +- `BookAppService`injeta `IRepository`qual é o repositório padrão da `Book`entidade. O ABP cria automaticamente repositórios padrão para cada raiz (ou entidade) agregada. Veja o [documento](https://docs.abp.io/en/abp/latest/Repositories) do [repositório](https://docs.abp.io/en/abp/latest/Repositories) . +- `BookAppService`usa `IObjectMapper`para converter `Book`objetos em `BookDto`objetos e `CreateUpdateBookDto`objetos em `Book`objetos. O modelo de inicialização usa a biblioteca [AutoMapper](http://automapper.org/) como o provedor de mapeamento de objetos. Você definiu os mapeamentos antes, para que funcionem conforme o esperado. + +### Controladores de API automática + +Você normalmente cria **controladores** para expor serviços de aplicativos como pontos de extremidade da **API HTTP** . Assim, permite que navegadores ou clientes de terceiros os chamem via AJAX. O ABP pode configurar [**automaticamente**](https://docs.abp.io/en/abp/latest/AspNetCore/Auto-API-Controllers) seus serviços de aplicativo como controladores de API MVC por convenção. + +#### UI do Swagger + +O modelo de inicialização está configurado para executar a [interface do usuário](https://swagger.io/tools/swagger-ui/) do [swagger](https://swagger.io/tools/swagger-ui/) usando a biblioteca [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) . Execute o aplicativo e insira `https://localhost:XXXX/swagger/`(substitua XXXX por sua própria porta) como URL no seu navegador. + +Você verá alguns pontos de extremidade de serviço internos, bem como o `Book`serviço e seus pontos de extremidade no estilo REST: + +![livraria-arrogância](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png) + +O Swagger tem uma ótima interface para testar APIs. Você pode tentar executar a `[GET] /api/app/book`API para obter uma lista de livros. + +### Proxies dinâmicos de JavaScript + +É comum chamar pontos de extremidade da API HTTP via AJAX do lado do **JavaScript** . Você pode usar `$.ajax`ou outra ferramenta para chamar os pontos de extremidade. No entanto, o ABP oferece uma maneira melhor. + +O ABP cria **dinamicamente** **proxies** JavaScript para todos os pontos de extremidade da API. Portanto, você pode usar qualquer **terminal,** assim como chamar uma **função JavaScript** . + +#### Testando no console do desenvolvedor do navegador + +Você pode testar facilmente os proxies JavaScript usando o **Console** do **desenvolvedor** do seu navegador favorito agora. Execute o aplicativo, abra as **ferramentas de desenvolvedor** do navegador (atalho: F12), vá para a guia **Console** , digite o seguinte código e pressione enter: + +```js +acme.bookStore.book.getList({}).done(function (result) { console.log(result); }); +``` + +- `acme.bookStore`é o espaço para nome do `BookAppService`convertido em [camelCase](https://en.wikipedia.org/wiki/Camel_case) . +- `book`é o nome convencional para o `BookAppService`(postfix do AppService removido e convertido em camelCase). +- `getList`é o nome convencional para o `GetListAsync`método definido na `AsyncCrudAppService`classe base (postfix assíncrono removido e convertido em camelCase). +- `{}`O argumento é usado para enviar um objeto vazio ao `GetListAsync`método que normalmente espera um objeto do tipo `PagedAndSortedResultRequestDto`usado para enviar opções de paginação e classificação ao servidor (todas as propriedades são opcionais, para que você possa enviar um objeto vazio). +- `getList`A função retorna a `promise`. Portanto, você pode passar um retorno de chamada para a função `done`(ou `then`) para obter o resultado do servidor. + +A execução desse código produz a seguinte saída: + +![livraria-teste-js-proxy-getlist](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png) + +Você pode ver a **lista de livros** retornada do servidor. Você também pode verificar a guia de **rede** das ferramentas do desenvolvedor para ver a comunicação do cliente com o servidor: + +![livraria-teste-js-proxy-getlist-rede](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist-network.png) + +Vamos **criar um novo livro** usando a `create`função: + +```js +acme.bookStore.book.create({ name: 'Foundation', type: 7, publishDate: '1951-05-24', price: 21.5 }).done(function (result) { console.log('successfully created the book with id: ' + result.id); }); +``` + +Você deve ver uma mensagem no console, algo assim: + +``` +successfully created the book with id: f3f03580-c1aa-d6a9-072d-39e75c69f5c7 +``` + +Verifique a `Books`tabela no banco de dados para ver a nova linha do livro. Você pode tentar `get`, `update`e `delete`funciona mesmo. + +### Crie a página de livros + +É hora de criar algo visível e utilizável! Em vez do MVC clássico, usaremos a nova abordagem de [interface do usuário do Razor Pages,](https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start) recomendada pela Microsoft. + +Crie uma nova `Books`pasta na `Pages`pasta do `Acme.BookStore.Web`projeto e adicione uma nova página Razor denominada `Index.cshtml`: + +![livraria-add-index-page](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png) + +Abra `Index.cshtml`e altere o conteúdo, como mostrado abaixo: + +```html +@page +@using Acme.BookStore.Web.Pages.Books +@inherits Acme.BookStore.Web.Pages.BookStorePage +@model IndexModel + +

Books

+``` + +- Esse código altera a herança padrão do Razor View Page Model para que ele **herda** da `BookStorePage`classe (em vez de `PageModel`). A `BookStorePage`classe que acompanha o modelo de inicialização e fornece algumas propriedades / métodos compartilhados usados por todas as páginas. +- Verifique se o `IndexModel`( *Index.cshtml.cs)* possui o `Acme.BookStore.Pages.Books`espaço para nome ou atualize-o no `Index.cshtml`. + +#### Adicionar página de livros ao menu principal + +Abra a `BookStoreMenuContributor`classe na `Menus`pasta e adicione o seguinte código ao final do `ConfigureMainMenuAsync`método: + +```csharp +context.Menu.AddItem( + new ApplicationMenuItem("BooksStore", l["Menu:BookStore"]) + .AddItem(new ApplicationMenuItem("BooksStore.Books", l["Menu:Books"], url: "/Books")) +); +``` + +#### Localizando os itens de menu + +Os textos de localização estão localizados na `Localization/BookStore`pasta do `Acme.BookStore.Domain.Shared`projeto: + +![arquivos de localização de livraria](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png) + +Abra o `en.json`arquivo e adicione textos de localização `Menu:BookStore`e `Menu:Books`chaves ao final do arquivo: + +```json +{ + "culture": "en", + "texts": { + "Menu:BookStore": "Book Store", + "Menu:Books": "Books" + } +} +``` + +- O sistema de localização da ABP é construído no sistema de [localização padrão do ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization) e o estende de várias maneiras. Consulte o [documento de localização](https://docs.abp.io/en/abp/latest/Localization) para obter detalhes. +- Os nomes das chaves de localização são arbitrários. Você pode definir qualquer nome. Preferimos adicionar `Menu:`prefixo aos itens de menu para distinguir de outros textos. Se um texto não estiver definido no arquivo de localização, ele **recuará** para a chave de localização (comportamento padrão do ASP.NET Core). + +Execute o aplicativo e veja se o novo item de menu foi adicionado à barra superior: + +![itens-menu-livraria](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png) + +Quando você clica no item de menu Livros, você é redirecionado para a nova página Livros. + +#### Lista de livros + +Usaremos o plug-in [Datatables.net](https://datatables.net/) JQuery para mostrar a lista de tabelas na página. As tabelas de dados podem funcionar completamente via AJAX, são rápidas e oferecem uma boa experiência ao usuário. O plug-in Datatables está configurado no modelo de inicialização, para que você possa usá-lo diretamente em qualquer página sem incluir nenhum estilo ou arquivo de script em sua página. + +##### Index.cshtml + +Altere o `Pages/Books/Index.cshtml`seguinte: + +```html +@page +@inherits Acme.BookStore.Web.Pages.BookStorePage +@model Acme.BookStore.Web.Pages.Books.IndexModel +@section scripts +{ + +} + + +

@L["Books"]

+
+ + + + + @L["Name"] + @L["Type"] + @L["PublishDate"] + @L["Price"] + @L["CreationTime"] + + + + +
+``` + +- `abp-script` [O auxiliar de marca](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro) é usado para adicionar **scripts** externos à página. Possui muitos recursos adicionais em comparação com a `script`tag padrão . Ele lida com **minificação** e **controle** de **versão,** por exemplo. Consulte o [documento de compactação e redução](https://docs.abp.io/en/abp/latest/AspNetCore/Bundling-Minification) para obter detalhes. +- `abp-card`e `abp-table`são **auxiliares de tags** para o [componente de cartão](http://getbootstrap.com/docs/4.1/components/card/) do Twitter Bootstrap . Existem muitos auxiliares de tag no ABP para usar facilmente a maioria dos componentes de [autoinicialização](https://getbootstrap.com/) . Você também pode usar tags HTML regulares em vez desses auxiliares de tag, mas o uso de tag reduz o código HTML e evita erros com a ajuda do intellisense e da verificação do tipo de tempo de compilação. Consulte o [documento auxiliares](https://docs.abp.io/en/abp/latest/AspNetCore/Tag-Helpers) da [tag](https://docs.abp.io/en/abp/latest/AspNetCore/Tag-Helpers) . +- Você pode **localizar** os nomes das colunas no arquivo de localização, como fez nos itens de menu acima. + +##### Adicionar um arquivo de script + +Crie um `index.js`arquivo JavaScript na `Pages/Books/`pasta: + +![arquivo-index-js-bookstore](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png) + +`index.js` o conteúdo é mostrado abaixo: + +```js +$(function () { + var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList), + columnDefs: [ + { data: "name" }, + { data: "type" }, + { data: "publishDate" }, + { data: "price" }, + { data: "creationTime" } + ] + })); +}); +``` + +- `abp.libs.datatables.createAjax` é uma função auxiliar para adaptar os proxies dinâmicos da API JavaScript da ABP ao formato do Datatable. +- `abp.libs.datatables.normalizeConfiguration`é outra função auxiliar. Não há necessidade de usá-lo, mas simplifica a configuração das tabelas de dados, fornecendo valores convencionais para as opções ausentes. +- `acme.bookStore.book.getList` é a função para obter a lista de livros (você já viu isso antes). +- Consulte [a documentação do Datatable](https://datatables.net/manual/) para obter mais opções de configuração. + +A interface do usuário final é mostrada abaixo: + +![livraria-lista-de-livros](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-book-list-2.png) + +### Próxima parte + +Veja a [próxima parte](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-II) deste tutorial. \ No newline at end of file diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-II.md b/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-II.md new file mode 100644 index 0000000000..7e6471d3ed --- /dev/null +++ b/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-II.md @@ -0,0 +1,466 @@ +## Tutorial do ASP.NET Core MVC - Parte II + +### Sobre este tutorial + +Esta é a segunda parte da série de tutoriais do ASP.NET Core MVC. Veja todas as peças: + +- [Parte I: Crie o projeto e uma página da lista de livros](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-I) +- **Parte II: Criar, atualizar e excluir livros (este tutorial)** +- [Parte III: Testes de Integração](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-III) + +Você pode acessar o **código fonte** do aplicativo [no repositório GitHub](https://github.com/volosoft/abp/tree/master/samples/BookStore) . + +> Você também pode assistir a [este curso em vídeo](https://amazingsolutions.teachable.com/p/lets-build-the-bookstore-application) preparado por um membro da comunidade ABP, com base neste tutorial. + +### Criando um novo livro + +Nesta seção, você aprenderá como criar um novo formulário de diálogo modal para criar um novo livro. A caixa de diálogo do resultado será assim: + +![livraria-criar-diálogo](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog-2.png) + +#### Crie o formulário modal + +Crie uma nova página de navalha, nomeada `CreateModal.cshtml`sob a `Pages/Books`pasta do `Acme.BookStore.Web`projeto: + +![livraria-adicionar-criar-diálogo](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png) + +##### CreateModal.cshtml.cs + +Abra o `CreateModal.cshtml.cs`arquivo ( `CreateModalModel`classe) e substitua pelo seguinte código: + +```csharp +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Acme.BookStore.Web.Pages.Books +{ + public class CreateModalModel : BookStorePageModel + { + [BindProperty] + public CreateUpdateBookDto Book { get; set; } + + private readonly IBookAppService _bookAppService; + + public CreateModalModel(IBookAppService bookAppService) + { + _bookAppService = bookAppService; + } + + public async Task OnPostAsync() + { + await _bookAppService.CreateAsync(Book); + return NoContent(); + } + } +} +``` + + + +- Esta classe é derivada do em `BookStorePageModel`vez do padrão `PageModel`. `BookStorePageModel`herda o `PageModel`e adiciona algumas propriedades / métodos comuns que podem ser usados pelas classes de modelo de página. +- `[BindProperty]`O atributo na `Book`propriedade vincula os dados de solicitação posterior a essa propriedade. +- Essa classe simplesmente injeta o `IBookAppService`em seu construtor e chama o `CreateAsync`método no `OnPostAsync`manipulador. + +##### CreateModal.cshtml + +Abra o `CreateModal.cshtml`arquivo e cole o código abaixo: + +```html +@page +@inherits Acme.BookStore.Web.Pages.BookStorePage +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@model Acme.BookStore.Web.Pages.Books.CreateModalModel +@{ + Layout = null; +} + + + + + + + + + +``` + + + +- Este modal usa o + + ``` + abp-dynamic-form + ``` + + auxiliar de marca para criar automaticamente o formulário a partir da + + ``` + CreateBookViewModel + ``` + + classe. + + - `abp-model`O atributo indica o objeto do modelo, a `Book`propriedade neste caso. + - `data-ajaxForm` O atributo faz com que o formulário seja enviado via AJAX, em vez de uma postagem de página clássica. + - `abp-form-content`O auxiliar de marca é um espaço reservado para renderizar os controles do formulário (isso é opcional e necessário apenas se você tiver adicionado outro conteúdo à `abp-dynamic-form`marca, como nesta página). + +#### Adicione o botão "Novo livro" + +Abra `Pages/Books/Index.cshtml`e altere a `abp-card-header`tag, como mostrado abaixo: + +```html + + + +

@L["Books"]

+
+ + + +
+
+``` + + + +Acabei de adicionar um botão **Novo livro** no canto **superior direito** da tabela: + +![livraria-novo-livro-botão](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png) + +Abra o `pages/books/index.js`e adicione o seguinte código logo após a configuração da tabela de dados: + +```js +var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal'); + +createModal.onResult(function () { + dataTable.ajax.reload(); +}); + +$('#NewBookButton').click(function (e) { + e.preventDefault(); + createModal.open(); +}); +``` + + + +- `abp.ModalManager`é uma classe auxiliar para abrir e gerenciar modais no lado do cliente. Ele usa internamente o modal padrão do Twitter Bootstrap, mas abstrai muitos detalhes, fornecendo uma API simples. + +Agora, você pode **executar o aplicativo** e adicionar novos livros usando o novo formulário modal. + +### Atualizando um livro existente + +Crie uma nova página de navalha, nomeada `EditModal.cshtml`sob a `Pages/Books`pasta do `Acme.BookStore.Web`projeto: + +![livraria-adicionar-editar-diálogo](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png) + +#### EditModal.cshtml.cs + +Abra o `EditModal.cshtml.cs`arquivo ( `EditModalModel`classe) e substitua pelo seguinte código: + +```csharp +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace Acme.BookStore.Web.Pages.Books +{ + public class EditModalModel : BookStorePageModel + { + [HiddenInput] + [BindProperty(SupportsGet = true)] + public Guid Id { get; set; } + + [BindProperty] + public CreateUpdateBookDto Book { get; set; } + + private readonly IBookAppService _bookAppService; + + public EditModalModel(IBookAppService bookAppService) + { + _bookAppService = bookAppService; + } + + public async Task OnGetAsync() + { + var bookDto = await _bookAppService.GetAsync(Id); + Book = ObjectMapper.Map(bookDto); + } + + public async Task OnPostAsync() + { + await _bookAppService.UpdateAsync(Id, Book); + return NoContent(); + } + } +} +``` + + + +- `[HiddenInput]`e `[BindProperty]`são atributos padrão do ASP.NET Core MVC. Utilizado `SupportsGet`para obter o valor do ID a partir do parâmetro da string de consulta da solicitação. +- Mapeado `BookDto`(recebido de `BookAppService.GetAsync`) para `CreateUpdateBookDto`no `GetAsync`método +- O `OnPostAsync`simplesmente usa `BookAppService.UpdateAsync`para atualizar a entidade. + +#### Mapeamento de BookDto para CreateUpdateBookDto + +A fim de executar `BookDto`a `CreateUpdateBookDto`opor mapeamento, abrir o `BookStoreWebAutoMapperProfile.cs`no `Acme.BookStore.Web`projecto e alterá-lo como se mostra abaixo: + +```csharp +using AutoMapper; + +namespace Acme.BookStore.Web +{ + public class BookStoreWebAutoMapperProfile : Profile + { + public BookStoreWebAutoMapperProfile() + { + CreateMap(); + } + } +} +``` + + + +- Apenas adicionado `CreateMap();`como a definição de mapeamento. + +#### EditModal.cshtml + +Substitua o `EditModal.cshtml`conteúdo pelo seguinte: + +```html +@page +@inherits Acme.BookStore.Web.Pages.BookStorePage +@using Acme.BookStore.Web.Pages.Books +@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal +@model EditModalModel +@{ + Layout = null; +} + + + + + + + + + + +``` + + + +Esta página é muito semelhante à `CreateModal.cshtml`exceção; + +- Ele inclui um `abp-input`para a `Id`propriedade armazenar o ID do livro de edição (que é uma entrada oculta). +- Ele usa `Books/EditModal`como URL de postagem e texto de *atualização* como cabeçalho modal. + +#### Adicione o menu suspenso "Ações" à tabela + +Adicionaremos um botão suspenso ("Ações") para cada linha da tabela. A interface do usuário final é assim: + +![livraria-livros-mesa-ações](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png) + +Abra a `Pages/Books/Index.cshtml`página e altere a seção da tabela como mostrado abaixo: + +```html + + + + @L["Actions"] + @L["Name"] + @L["Type"] + @L["PublishDate"] + @L["Price"] + @L["CreationTime"] + + + +``` + + + +- Acabei de adicionar uma nova `th`tag para as "Ações". + +Abra `pages/books/index.js`e substitua o conteúdo como abaixo: + +```js +$(function () { + + var l = abp.localization.getResource('BookStore'); + + var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal'); + var editModal = new abp.ModalManager(abp.appPath + 'Books/EditModal'); + + var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + order: [[1, "asc"]], + ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList), + columnDefs: [ + { + rowAction: { + items: + [ + { + text: l('Edit'), + action: function (data) { + editModal.open({ id: data.record.id }); + } + } + ] + } + }, + { data: "name" }, + { data: "type" }, + { data: "publishDate" }, + { data: "price" }, + { data: "creationTime" } + ] + })); + + createModal.onResult(function () { + dataTable.ajax.reload(); + }); + + editModal.onResult(function () { + dataTable.ajax.reload(); + }); + + $('#NewBookButton').click(function (e) { + e.preventDefault(); + createModal.open(); + }); +}); +``` + + + +- Utilizado `abp.localization.getResource('BookStore')`para poder usar os mesmos textos de localização definidos no lado do servidor. +- Adicionado um novo `ModalManager`nome `createModal`para abrir a caixa de diálogo criar modal. +- Adicionado um novo `ModalManager`nome `editModal`para abrir a caixa de diálogo modal de edição. +- Adicionada uma nova coluna no início da `columnDefs`seção. Esta coluna é usada para o botão suspenso "Ações". +- A ação "Novo livro" simplesmente chama `createModal.open`para abrir a caixa de diálogo Criar. +- A ação "Editar" simplesmente chama `editModal.open`para abrir a caixa de diálogo de edição. `Você pode executar o aplicativo e editar qualquer livro selecionando a ação de edição. + +### Exclusão de um livro existente + +Abra o `pages/books/index.js`e adicione um novo item ao `rowAction` `items`: + +```js +{ + text: l('Delete'), + confirmMessage: function (data) { + return l('BookDeletionConfirmationMessage', data.record.name); + }, + action: function (data) { + acme.bookStore.book + .delete(data.record.id) + .then(function() { + abp.notify.info(l('SuccessfullyDeleted')); + dataTable.ajax.reload(); + }); + } +} +``` + + + +- `confirmMessage`A opção é usada para fazer uma pergunta de confirmação antes de executar o `action`. +- Utilizou a `acme.bookStore.book.delete`função de proxy javascript para executar uma solicitação AJAX para excluir um livro. +- `abp.notify.info` é usado para mostrar uma notificação toastr logo após a exclusão. + +O `index.js`conteúdo final é mostrado abaixo: + +```js +$(function () { + + var l = abp.localization.getResource('BookStore'); + + var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal'); + var editModal = new abp.ModalManager(abp.appPath + 'Books/EditModal'); + + var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({ + processing: true, + serverSide: true, + paging: true, + searching: false, + autoWidth: false, + scrollCollapse: true, + order: [[1, "asc"]], + ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList), + columnDefs: [ + { + rowAction: { + items: + [ + { + text: l('Edit'), + action: function (data) { + editModal.open({ id: data.record.id }); + } + }, + { + text: l('Delete'), + confirmMessage: function (data) { + return l('BookDeletionConfirmationMessage', data.record.name); + }, + action: function (data) { + acme.bookStore.book + .delete(data.record.id) + .then(function() { + abp.notify.info(l('SuccessfullyDeleted')); + dataTable.ajax.reload(); + }); + } + } + ] + } + }, + { data: "name" }, + { data: "type" }, + { data: "publishDate" }, + { data: "price" }, + { data: "creationTime" } + ] + })); + + createModal.onResult(function () { + dataTable.ajax.reload(); + }); + + editModal.onResult(function () { + dataTable.ajax.reload(); + }); + + $('#NewBookButton').click(function (e) { + e.preventDefault(); + createModal.open(); + }); +}); +``` + + + +Abra o `en.json`no `Acme.BookStore.Domain.Shared`projeto e adicione a seguinte linha: + +```json +"BookDeletionConfirmationMessage": "Are you sure to delete the book {0}?" +``` + + + +Execute o aplicativo e tente excluir um livro. + +### Próxima parte + +Veja a [próxima parte](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-III) deste tutorial. \ No newline at end of file diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-III.md b/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-III.md new file mode 100644 index 0000000000..ff1ad29a25 --- /dev/null +++ b/docs/pt-BR/Tutorials/AspNetCore-Mvc/Part-III.md @@ -0,0 +1,182 @@ +## Tutorial do ASP.NET Core MVC - Parte III + +### Sobre este tutorial + +Esta é a terceira parte da série de tutoriais do ASP.NET Core MVC. Veja todas as peças: + +- [Parte I: Crie o projeto e uma página da lista de livros](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-I) +- [Parte II: Criar, atualizar e excluir livros](https://docs.abp.io/en/abp/latest/Tutorials/AspNetCore-Mvc/Part-II) +- **Parte III: Testes de Integração (este tutorial)** + +Você pode acessar o **código fonte** do aplicativo [no repositório GitHub](https://github.com/volosoft/abp/tree/master/samples/BookStore) . + +> Você também pode assistir a [este curso em vídeo](https://amazingsolutions.teachable.com/p/lets-build-the-bookstore-application) preparado por um membro da comunidade ABP, com base neste tutorial. + +### Testar projetos na solução + +Existem vários projetos de teste na solução: + +![livraria-teste-projetos-v2](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png) + +Cada projeto é usado para testar o projeto de aplicativo relacionado. Os projetos de teste usam as seguintes bibliotecas para teste: + +- [xunit](https://xunit.github.io/) como a principal estrutura de teste. +- [Altamente](http://shouldly.readthedocs.io/en/latest/) como uma biblioteca de asserções. +- [NSubstitute](http://nsubstitute.github.io/) como uma biblioteca de zombaria. + +### Adicionando dados de teste + +O modelo de inicialização contém a `BookStoreTestDataSeedContributor`classe no `Acme.BookStore.TestBase`projeto que cria alguns dados para executar os testes. + +Mude a `BookStoreTestDataSeedContributor`classe como mostrado abaixo: + +```csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Guids; + +namespace Acme.BookStore +{ + public class BookStoreTestDataSeedContributor + : IDataSeedContributor, ITransientDependency + { + private readonly IRepository _bookRepository; + private readonly IGuidGenerator _guidGenerator; + + public BookStoreTestDataSeedContributor( + IRepository bookRepository, + IGuidGenerator guidGenerator) + { + _bookRepository = bookRepository; + _guidGenerator = guidGenerator; + } + + public async Task SeedAsync(DataSeedContext context) + { + await _bookRepository.InsertAsync( + new Book + { + Id = _guidGenerator.Create(), + Name = "Test book 1", + Type = BookType.Fantastic, + PublishDate = new DateTime(2015, 05, 24), + Price = 21 + } + ); + + await _bookRepository.InsertAsync( + new Book + { + Id = _guidGenerator.Create(), + Name = "Test book 2", + Type = BookType.Science, + PublishDate = new DateTime(2014, 02, 11), + Price = 15 + } + ); + } + } +} +``` + +- Injetado `IRepository`e usado no `SeedAsync`para criar duas entidades de livro como dados de teste. +- `IGuidGenerator`Serviço usado para criar GUIDs. Embora `Guid.NewGuid()`funcionasse perfeitamente para testes, `IGuidGenerator`possui recursos adicionais especialmente importantes ao usar bancos de dados reais (consulte o [documento de geração](https://docs.abp.io/en/abp/latest/Guid-Generation) do [Guid](https://docs.abp.io/en/abp/latest/Guid-Generation) para obter mais informações). + +### Testando o BookAppService + +Crie uma classe de teste denominada `BookAppService_Tests`no `Acme.BookStore.Application.Tests`projeto: + +```csharp +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Application.Dtos; +using Xunit; + +namespace Acme.BookStore +{ + public class BookAppService_Tests : BookStoreApplicationTestBase + { + private readonly IBookAppService _bookAppService; + + public BookAppService_Tests() + { + _bookAppService = GetRequiredService(); + } + + [Fact] + public async Task Should_Get_List_Of_Books() + { + //Act + var result = await _bookAppService.GetListAsync( + new PagedAndSortedResultRequestDto() + ); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.ShouldContain(b => b.Name == "Test book 1"); + } + } +} +``` + +- `Should_Get_List_Of_Books`O teste simplesmente usa o `BookAppService.GetListAsync`método para obter e verificar a lista de usuários. + +Adicione um novo teste que crie um novo livro válido: + +```csharp +[Fact] +public async Task Should_Create_A_Valid_Book() +{ + //Act + var result = await _bookAppService.CreateAsync( + new CreateUpdateBookDto + { + Name = "New test book 42", + Price = 10, + PublishDate = DateTime.Now, + Type = BookType.ScienceFiction + } + ); + + //Assert + result.Id.ShouldNotBe(Guid.Empty); + result.Name.ShouldBe("New test book 42"); +} +``` + +Adicione um novo teste que tente criar um livro inválido e falhe: + +```csharp +[Fact] +public async Task Should_Not_Create_A_Book_Without_Name() +{ + var exception = await Assert.ThrowsAsync(async () => + { + await _bookAppService.CreateAsync( + new CreateUpdateBookDto + { + Name = "", + Price = 10, + PublishDate = DateTime.Now, + Type = BookType.ScienceFiction + } + ); + }); + + exception.ValidationErrors + .ShouldContain(err => err.MemberNames.Any(mem => mem == "Name")); +} +``` + + + +- Como o `Name`está vazio, o ABP lança um `AbpValidationException`. + +Abra a **janela Test Explorer** (use o menu Test -> Windows -> Test Explorer, se não estiver visível) e **execute Todos os** testes: + +![testes de serviço de livraria](https://raw.githubusercontent.com/abpframework/abp/master/docs/en/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png) + +Parabéns, ícones verdes mostram que os testes foram aprovados com sucesso! \ No newline at end of file diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png new file mode 100644 index 0000000000..fcadfd7a82 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-create-dialog-v2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png new file mode 100644 index 0000000000..b28d8736dd Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-edit-dialog.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png new file mode 100644 index 0000000000..2606bbab32 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-add-index-page-v2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png new file mode 100644 index 0000000000..942d2832a6 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-appservice-tests.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list-2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list-2.png new file mode 100644 index 0000000000..a7d49a661b Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list-2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list.png new file mode 100644 index 0000000000..f531e6f457 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-book-list.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png new file mode 100644 index 0000000000..bc1d4e3f6f Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table-actions.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png new file mode 100644 index 0000000000..3cc8d7ca18 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-books-table.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog-2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog-2.png new file mode 100644 index 0000000000..3d5f1e8582 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog-2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog.png new file mode 100644 index 0000000000..4691d3c8fa Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-dialog.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-template.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-template.png new file mode 100644 index 0000000000..7cc96c8c94 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-create-template.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-homepage.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-homepage.png new file mode 100644 index 0000000000..5e5b512220 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-homepage.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png new file mode 100644 index 0000000000..1ba9a48600 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-index-js-file-v2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png new file mode 100644 index 0000000000..79314dd2dc Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-localization-files-v2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png new file mode 100644 index 0000000000..255defb707 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-menu-items.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png new file mode 100644 index 0000000000..dfd4b5d8aa Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-new-book-button.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png new file mode 100644 index 0000000000..edf2826361 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration-v2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration.png new file mode 100644 index 0000000000..5d29f4d32b Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-pmc-add-book-migration.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png new file mode 100644 index 0000000000..437c772503 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-swagger.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist-network.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist-network.png new file mode 100644 index 0000000000..2f2c42fd9e Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist-network.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png new file mode 100644 index 0000000000..47af48b1ea Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-js-proxy-getlist.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png new file mode 100644 index 0000000000..8701164d75 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-test-projects-v2.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-user-management.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-user-management.png new file mode 100644 index 0000000000..bc3c176557 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-user-management.png differ diff --git a/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v3.png b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v3.png new file mode 100644 index 0000000000..307e3516a5 Binary files /dev/null and b/docs/pt-BR/Tutorials/AspNetCore-Mvc/images/bookstore-visual-studio-solution-v3.png differ diff --git a/docs/pt-BR/images/MonthlyProfitWidgetFiles.png b/docs/pt-BR/images/MonthlyProfitWidgetFiles.png new file mode 100644 index 0000000000..e1e9d316f5 Binary files /dev/null and b/docs/pt-BR/images/MonthlyProfitWidgetFiles.png differ diff --git a/docs/pt-BR/images/bookstore-apis.png b/docs/pt-BR/images/bookstore-apis.png new file mode 100644 index 0000000000..aedd79c7f1 Binary files /dev/null and b/docs/pt-BR/images/bookstore-apis.png differ diff --git a/docs/pt-BR/images/bookstore-create-template.png b/docs/pt-BR/images/bookstore-create-template.png new file mode 100644 index 0000000000..7cc96c8c94 Binary files /dev/null and b/docs/pt-BR/images/bookstore-create-template.png differ diff --git a/docs/pt-BR/images/bookstore-homepage.png b/docs/pt-BR/images/bookstore-homepage.png new file mode 100644 index 0000000000..5e5b512220 Binary files /dev/null and b/docs/pt-BR/images/bookstore-homepage.png differ diff --git a/docs/pt-BR/images/bookstore-swagger-ui-host.png b/docs/pt-BR/images/bookstore-swagger-ui-host.png new file mode 100644 index 0000000000..74ff73f7e3 Binary files /dev/null and b/docs/pt-BR/images/bookstore-swagger-ui-host.png differ diff --git a/docs/pt-BR/images/bookstore-user-management-v2.png b/docs/pt-BR/images/bookstore-user-management-v2.png new file mode 100644 index 0000000000..dd95740754 Binary files /dev/null and b/docs/pt-BR/images/bookstore-user-management-v2.png differ diff --git a/docs/pt-BR/images/bookstore-visual-studio-solution-for-spa.png b/docs/pt-BR/images/bookstore-visual-studio-solution-for-spa.png new file mode 100644 index 0000000000..5a5a283c7d Binary files /dev/null and b/docs/pt-BR/images/bookstore-visual-studio-solution-for-spa.png differ diff --git a/docs/pt-BR/images/bookstore-visual-studio-solution-tiered.png b/docs/pt-BR/images/bookstore-visual-studio-solution-tiered.png new file mode 100644 index 0000000000..19662bf731 Binary files /dev/null and b/docs/pt-BR/images/bookstore-visual-studio-solution-tiered.png differ diff --git a/docs/pt-BR/images/bookstore-visual-studio-solution-v3.png b/docs/pt-BR/images/bookstore-visual-studio-solution-v3.png new file mode 100644 index 0000000000..307e3516a5 Binary files /dev/null and b/docs/pt-BR/images/bookstore-visual-studio-solution-v3.png differ diff --git a/docs/pt-BR/images/build-action-embedded-resource-sample.png b/docs/pt-BR/images/build-action-embedded-resource-sample.png new file mode 100644 index 0000000000..d001c5d19f Binary files /dev/null and b/docs/pt-BR/images/build-action-embedded-resource-sample.png differ diff --git a/docs/pt-BR/images/create-new-aspnet-core-application.png b/docs/pt-BR/images/create-new-aspnet-core-application.png new file mode 100644 index 0000000000..fe78b9051d Binary files /dev/null and b/docs/pt-BR/images/create-new-aspnet-core-application.png differ diff --git a/docs/pt-BR/images/create-new-net-core-console-application.png b/docs/pt-BR/images/create-new-net-core-console-application.png new file mode 100644 index 0000000000..c5f39bfb37 Binary files /dev/null and b/docs/pt-BR/images/create-new-net-core-console-application.png differ diff --git a/docs/pt-BR/images/dashboard1.png b/docs/pt-BR/images/dashboard1.png new file mode 100644 index 0000000000..4102bbd4c1 Binary files /dev/null and b/docs/pt-BR/images/dashboard1.png differ diff --git a/docs/pt-BR/images/db-migrator-app.png b/docs/pt-BR/images/db-migrator-app.png new file mode 100644 index 0000000000..ace6abb226 Binary files /dev/null and b/docs/pt-BR/images/db-migrator-app.png differ diff --git a/docs/pt-BR/images/docs-create-project.jpg b/docs/pt-BR/images/docs-create-project.jpg new file mode 100644 index 0000000000..742f5e307f Binary files /dev/null and b/docs/pt-BR/images/docs-create-project.jpg differ diff --git a/docs/pt-BR/images/docs-module_download-new-abp-project.png b/docs/pt-BR/images/docs-module_download-new-abp-project.png new file mode 100644 index 0000000000..0da3b7a67a Binary files /dev/null and b/docs/pt-BR/images/docs-module_download-new-abp-project.png differ diff --git a/docs/pt-BR/images/docs-module_download-sample-navigation-menu.png b/docs/pt-BR/images/docs-module_download-sample-navigation-menu.png new file mode 100644 index 0000000000..9a1232f198 Binary files /dev/null and b/docs/pt-BR/images/docs-module_download-sample-navigation-menu.png differ diff --git a/docs/pt-BR/images/docs-module_solution-explorer.png b/docs/pt-BR/images/docs-module_solution-explorer.png new file mode 100644 index 0000000000..cafc38f0b0 Binary files /dev/null and b/docs/pt-BR/images/docs-module_solution-explorer.png differ diff --git a/docs/pt-BR/images/github-access-token-private-repo.jpg b/docs/pt-BR/images/github-access-token-private-repo.jpg new file mode 100644 index 0000000000..5bc53cc63d Binary files /dev/null and b/docs/pt-BR/images/github-access-token-private-repo.jpg differ diff --git a/docs/pt-BR/images/github-access-token-public-repo.jpg b/docs/pt-BR/images/github-access-token-public-repo.jpg new file mode 100644 index 0000000000..b909c2cfe5 Binary files /dev/null and b/docs/pt-BR/images/github-access-token-public-repo.jpg differ diff --git a/docs/pt-BR/images/github-myusername.jpg b/docs/pt-BR/images/github-myusername.jpg new file mode 100644 index 0000000000..4ac57eeed4 Binary files /dev/null and b/docs/pt-BR/images/github-myusername.jpg differ diff --git a/docs/pt-BR/images/issuemanagement-module-solution.png b/docs/pt-BR/images/issuemanagement-module-solution.png new file mode 100644 index 0000000000..181924dd90 Binary files /dev/null and b/docs/pt-BR/images/issuemanagement-module-solution.png differ diff --git a/docs/pt-BR/images/layered-project-dependencies-module.png b/docs/pt-BR/images/layered-project-dependencies-module.png new file mode 100644 index 0000000000..7592f49878 Binary files /dev/null and b/docs/pt-BR/images/layered-project-dependencies-module.png differ diff --git a/docs/pt-BR/images/layered-project-dependencies.png b/docs/pt-BR/images/layered-project-dependencies.png new file mode 100644 index 0000000000..c5fd1b3504 Binary files /dev/null and b/docs/pt-BR/images/layered-project-dependencies.png differ diff --git a/docs/pt-BR/images/localization-resource-json-files.png b/docs/pt-BR/images/localization-resource-json-files.png new file mode 100644 index 0000000000..bbbd78c320 Binary files /dev/null and b/docs/pt-BR/images/localization-resource-json-files.png differ diff --git a/docs/pt-BR/images/microservice-sample-authserver-home.png b/docs/pt-BR/images/microservice-sample-authserver-home.png new file mode 100644 index 0000000000..7ae62ad6d5 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-authserver-home.png differ diff --git a/docs/pt-BR/images/microservice-sample-authserver-login.png b/docs/pt-BR/images/microservice-sample-authserver-login.png new file mode 100644 index 0000000000..f6e8dfaa9f Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-authserver-login.png differ diff --git a/docs/pt-BR/images/microservice-sample-backend-ui-permissions.png b/docs/pt-BR/images/microservice-sample-backend-ui-permissions.png new file mode 100644 index 0000000000..02769be3e5 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-backend-ui-permissions.png differ diff --git a/docs/pt-BR/images/microservice-sample-backend-ui.png b/docs/pt-BR/images/microservice-sample-backend-ui.png new file mode 100644 index 0000000000..0935a6047a Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-backend-ui.png differ diff --git a/docs/pt-BR/images/microservice-sample-blogservice-permission-in-database.png b/docs/pt-BR/images/microservice-sample-blogservice-permission-in-database.png new file mode 100644 index 0000000000..f99cd39893 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-blogservice-permission-in-database.png differ diff --git a/docs/pt-BR/images/microservice-sample-diagram-2.png b/docs/pt-BR/images/microservice-sample-diagram-2.png new file mode 100644 index 0000000000..17aea07098 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-diagram-2.png differ diff --git a/docs/pt-BR/images/microservice-sample-diagram.png b/docs/pt-BR/images/microservice-sample-diagram.png new file mode 100644 index 0000000000..b1d9f6c66e Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-diagram.png differ diff --git a/docs/pt-BR/images/microservice-sample-kibana-1.png b/docs/pt-BR/images/microservice-sample-kibana-1.png new file mode 100644 index 0000000000..f3a51bd349 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-kibana-1.png differ diff --git a/docs/pt-BR/images/microservice-sample-kibana-2.png b/docs/pt-BR/images/microservice-sample-kibana-2.png new file mode 100644 index 0000000000..31b281486c Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-kibana-2.png differ diff --git a/docs/pt-BR/images/microservice-sample-product-module-in-solution.png b/docs/pt-BR/images/microservice-sample-product-module-in-solution.png new file mode 100644 index 0000000000..27e841cdd5 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-product-module-in-solution.png differ diff --git a/docs/pt-BR/images/microservice-sample-public-product-list.png b/docs/pt-BR/images/microservice-sample-public-product-list.png new file mode 100644 index 0000000000..cf8649bbe5 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-public-product-list.png differ diff --git a/docs/pt-BR/images/microservice-sample-solution.png b/docs/pt-BR/images/microservice-sample-solution.png new file mode 100644 index 0000000000..4c8344ed68 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-solution.png differ diff --git a/docs/pt-BR/images/microservice-sample-update-database-authserver.png b/docs/pt-BR/images/microservice-sample-update-database-authserver.png new file mode 100644 index 0000000000..689019b587 Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-update-database-authserver.png differ diff --git a/docs/pt-BR/images/microservice-sample-update-database-products.png b/docs/pt-BR/images/microservice-sample-update-database-products.png new file mode 100644 index 0000000000..b49c2a8f8e Binary files /dev/null and b/docs/pt-BR/images/microservice-sample-update-database-products.png differ diff --git a/docs/pt-BR/images/module-layers-and-packages.jpg b/docs/pt-BR/images/module-layers-and-packages.jpg new file mode 100644 index 0000000000..f71a91eb8d Binary files /dev/null and b/docs/pt-BR/images/module-layers-and-packages.jpg differ diff --git a/docs/pt-BR/images/night-build-add-nuget-package.png b/docs/pt-BR/images/night-build-add-nuget-package.png new file mode 100644 index 0000000000..c3621ef7d9 Binary files /dev/null and b/docs/pt-BR/images/night-build-add-nuget-package.png differ diff --git a/docs/pt-BR/images/night-build-add-nuget-source.png b/docs/pt-BR/images/night-build-add-nuget-source.png new file mode 100644 index 0000000000..8fd4b9365a Binary files /dev/null and b/docs/pt-BR/images/night-build-add-nuget-source.png differ diff --git a/docs/pt-BR/images/pcm-update-database-v2.png b/docs/pt-BR/images/pcm-update-database-v2.png new file mode 100644 index 0000000000..d5bb9c2975 Binary files /dev/null and b/docs/pt-BR/images/pcm-update-database-v2.png differ diff --git a/docs/pt-BR/images/pcm-update-database.png b/docs/pt-BR/images/pcm-update-database.png new file mode 100644 index 0000000000..ac53f0db4f Binary files /dev/null and b/docs/pt-BR/images/pcm-update-database.png differ diff --git a/docs/pt-BR/images/select-empty-web-application.png b/docs/pt-BR/images/select-empty-web-application.png new file mode 100644 index 0000000000..b0cd89a27a Binary files /dev/null and b/docs/pt-BR/images/select-empty-web-application.png differ diff --git a/docs/pt-BR/images/set-as-startup-project.png b/docs/pt-BR/images/set-as-startup-project.png new file mode 100644 index 0000000000..13da5caf6c Binary files /dev/null and b/docs/pt-BR/images/set-as-startup-project.png differ diff --git a/docs/pt-BR/images/tiered-solution-applications.png b/docs/pt-BR/images/tiered-solution-applications.png new file mode 100644 index 0000000000..fb6ede7ac5 Binary files /dev/null and b/docs/pt-BR/images/tiered-solution-applications.png differ diff --git a/docs/pt-BR/images/tiered-solution-servers.png b/docs/pt-BR/images/tiered-solution-servers.png new file mode 100644 index 0000000000..3c999b4b45 Binary files /dev/null and b/docs/pt-BR/images/tiered-solution-servers.png differ diff --git a/docs/pt-BR/images/volodocs-iis-add-website.png b/docs/pt-BR/images/volodocs-iis-add-website.png new file mode 100644 index 0000000000..878b3e8f0c Binary files /dev/null and b/docs/pt-BR/images/volodocs-iis-add-website.png differ diff --git a/docs/pt-BR/images/volodocs-iis-application-pool.png b/docs/pt-BR/images/volodocs-iis-application-pool.png new file mode 100644 index 0000000000..cc5186f50b Binary files /dev/null and b/docs/pt-BR/images/volodocs-iis-application-pool.png differ diff --git a/docs/pt-BR/images/widget-basic-files.png b/docs/pt-BR/images/widget-basic-files.png new file mode 100644 index 0000000000..bf5f122d42 Binary files /dev/null and b/docs/pt-BR/images/widget-basic-files.png differ