{"id":17636020,"url":"https://github.com/phjb/app-mvc","last_synced_at":"2025-04-14T06:22:27.450Z","repository":{"id":120734373,"uuid":"233123671","full_name":"phjb/app-mvc","owner":"phjb","description":"Exemplo de criação do zero de um projeto utilizando o padrão MVC com o  ASP.NET Core 3.1 ","archived":false,"fork":false,"pushed_at":"2020-02-26T20:37:10.000Z","size":539,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T20:07:49.872Z","etag":null,"topics":["asp-net","asp-net-core","asp-net-mvc","dotnet","dotnet-core"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phjb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-10T20:17:43.000Z","updated_at":"2024-08-23T16:39:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"78c047fb-7ec9-4a5f-9797-13f00feceec5","html_url":"https://github.com/phjb/app-mvc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phjb%2Fapp-mvc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phjb%2Fapp-mvc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phjb%2Fapp-mvc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phjb%2Fapp-mvc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phjb","download_url":"https://codeload.github.com/phjb/app-mvc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248830907,"owners_count":21168369,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp-net","asp-net-core","asp-net-mvc","dotnet","dotnet-core"],"created_at":"2024-10-23T02:25:18.383Z","updated_at":"2025-04-14T06:22:27.414Z","avatar_url":"https://github.com/phjb.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n![](screenshots/phjb_2020.png)\n\n# Introdução\n\nEsse projeto é um exemplo prático de como desenvolver uma aplicação *`step by step`* utilizando o padrão **MVC** com o [asp.net core 3.1](https://dotnet.microsoft.com/download/dotnet-core/3.1).\n\n\n### Tecnologia\n* SDK do .NET Core\n```\n Version:   3.1.100\n Commit:    cd82f021f4\n```\n## \n\n### Editor de Código \n* [Visual Studio Code](https://code.visualstudio.com/)\n\n## \n\n### Extensões\nAs extensões do VS Code permitem adicionar idiomas, depuradores e ferramentas à sua instalação para dar suporte ao seu fluxo de trabalho de desenvolvimento. O rico modelo de extensibilidade do VS Code permite que os autores de extensões se conectem diretamente à interface do usuário do VS Code e contribuam com a funcionalidade por meio das mesmas APIs usadas pelo VS Code. [Veja mais aqui](https://code.visualstudio.com/docs/editor/extension-gallery/).\n\n### \n\n![](screenshots/my-extensions-to-vscode.png)\n\n##\n\n# O que é MVC?\n**MVC** é o acrônimo de *Model-View-Controller* (em português: Arquitetura *Modelo-Visão-Controle*) é um padrão de projeto de software, ou padrão de arquitetura de software formulado na década de 1970, focado no reuso de código e a separação de conceitos em três camadas interconectadas, onde a apresentação dos dados e interação dos usuários *`front-end`* são separados dos métodos que interagem com o banco de dados *`back-end`*. [Wikipedia](https://pt.wikipedia.org/wiki/MVC).\n\n**MVC** é nada mais que um padrão de arquitetura de software, separando sua aplicação em 3 camadas. A camada de interação do usuário(***view***), a camada de manipulação dos dados(***model***) e a camada de controle(***controller***). [Tableless](https://tableless.com.br/mvc-afinal-e-o-que/).\n\n![](screenshots/model-view-controller-architecture.gif)\n\n## Model\n\nSempre que você pensar em manipulação de dados, pense em model. Ele é responsável pela **leitura** e **escrita de dados**, e também de suas **validações**. [Tableless](https://tableless.com.br/mvc-afinal-e-o-que/).\n\n## View\n\nSimples: a camada de interação com o usuário. Ela apenas faz a **exibição dos dados**, sendo ela por meio de um html ou xml.\n[Tableless](https://tableless.com.br/mvc-afinal-e-o-que/).\n\n## Controller\n\nO responsável por **receber** todas as **requisições do usuário**. Seus métodos chamados *actions* são responsáveis por uma página, controlando qual `model` usar e qual `view` será mostrado ao usuário.\n[Tableless](https://tableless.com.br/mvc-afinal-e-o-que/).\n\n##\n\n# Um pouco de *Command Line Interface*\nUsando um **terminal** que pode ser `cmd`, `PowerShell`, `Git Bash` ou outro da sua escolha, a primeira coisa a se fazer é escolher o nosso *template*, o **dotnet** nos disponibiliza vários modelos. Para visualizar esses modelos bastar digitar no terminal\n```bash\ndotnet new\n```\nComo resultado teremos obteremos:\n```bash\nTemplates                                         Short Name               Language          Tags\n----------------------------------------------------------------------------------------------------------------------------------\nConsole Application                               console                  [C#], F#, VB      Common/Console\nClass library                                     classlib                 [C#], F#, VB      Common/Library\nWPF Application                                   wpf                      [C#]              Common/WPF\nWPF Class library                                 wpflib                   [C#]              Common/WPF\nWPF Custom Control Library                        wpfcustomcontrollib      [C#]              Common/WPF\nWPF User Control Library                          wpfusercontrollib        [C#]              Common/WPF\nWindows Forms (WinForms) Application              winforms                 [C#]              Common/WinForms\nWindows Forms (WinForms) Class library            winformslib              [C#]              Common/WinForms\nWorker Service                                    worker                   [C#]              Common/Worker/Web\nUnit Test Project                                 mstest                   [C#], F#, VB      Test/MSTest\nNUnit 3 Test Project                              nunit                    [C#], F#, VB      Test/NUnit\nNUnit 3 Test Item                                 nunit-test               [C#], F#, VB      Test/NUnit\nxUnit Test Project                                xunit                    [C#], F#, VB      Test/xUnit\nRazor Component                                   razorcomponent           [C#]              Web/ASP.NET\nRazor Page                                        page                     [C#]              Web/ASP.NET\nMVC ViewImports                                   viewimports              [C#]              Web/ASP.NET\nMVC ViewStart                                     viewstart                [C#]              Web/ASP.NET\nBlazor Server App                                 blazorserver             [C#]              Web/Blazor\nASP.NET Core Empty                                web                      [C#], F#          Web/Empty\nASP.NET Core Web App (Model-View-Controller)      mvc                      [C#], F#          Web/MVC\nASP.NET Core Web App                              webapp                   [C#]              Web/MVC/Razor Pages\nASP.NET Core with Angular                         angular                  [C#]              Web/MVC/SPA\nASP.NET Core with React.js                        react                    [C#]              Web/MVC/SPA\nASP.NET Core with React.js and Redux              reactredux               [C#]              Web/MVC/SPA\nRazor Class Library                               razorclasslib            [C#]              Web/Razor/Library/Razor Class Library\nASP.NET Core Web API                              webapi                   [C#], F#          Web/WebAPI\nASP.NET Core gRPC Service                         grpc                     [C#]              Web/gRPC\ndotnet gitignore file                             gitignore                                  Config\nglobal.json file                                  globaljson                                 Config\nNuGet Config                                      nugetconfig                                Config\nDotnet local tool manifest file                   tool-manifest                              Config\nWeb Config                                        webconfig                                  Config\nSolution File                                     sln                                        Solution\nProtocol Buffer File                              proto                                      Web/gRPC\n```\nComo mencionado vamos desenvolver `do zero`, para isso precisaremos de um *template* vazio, então vamos utilizar o modelo `ASP.NET Core Empty` que tem como *short name* `web`.\n\nNovamente no **terminal** vamos digitar\n```bash\ndotnet new web -o app-mvc\n```\n\u003e ***-o app-mvc*** indica a pasta do nosso projeto!\n\nAgora vamos abrir o nosso projeto no **Visual Studio Code**. Basta digitar no terminal\n```bash\ncode .\n```\n\n## Mãos no *Visual Studio Code*\n\nCom o VS Code aberto vamos criar os 3 pastas do **MVC** `Models` `Views` `Controllers`. Por conversão criamos as pastas no *`Plural`*, aconselho a seguirmos essa conversão. \n\n![](screenshots/ss_1.png)\n\nAgora vamos criar a primeiro *Controller* chamada `HomeController.cs` que ficará dentro da pasta ***Controllers*** que acabamos de criar.\n\u003e A classe ***HomeController*** herda da classe base `Controller`. Para que funcione devemos a *diretiva* *`using Microsoft.AspNetCore.Mvc;`*\n\nCom isso nossa **`HomeController`** deverá ter o seguinte código\n\n```c#\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace app_mvc.Controllers\n{\n    public class HomeController:Controller\n    {\n        public ActionResult Index()\n        {\n            return View();\n        }\n    }\n}\n```\nAgora chegou a vez de criarmos nossa *View* e se chamará `Index.cshtml` e ficará dentra da pasta ***Views \u003e Home***.\n\nVamos adicionar uns códigos\n```html\n@{\n    ViewData[\"Title\"] = \"Index\";\n}\n\n\u003ch1\u003eNossa Primeira View\u003c/h1\u003e\n```\nChegou a hora de vermos os resultados no navegador :rocket:. Esperamos que apareça a frase\n\"**Nossa Primeira View**\".\n\n\n Para que isso aconteça vamos rodar a aplicação, no **terminal** vamos digitar\n```bash\ndotnet run\n```\n\u003e O ***dotnet*** nos disponibilizou a seguinte *Url*: [`http://localhost:5000/`](http://localhost:5000/).\n\n![](screenshots/ss_2.png)\n\n*what this is???* :scream:\n\n### Configurando as rotas\n\nNossa execução não funcionou como o esperado porque não configuramos as rota da aplicação :sweat_smile:\n\n\nEntão vamos configurar. \n\nAbra o arquivo chamado ***Startup.cs*** e no método *ConfigureServices* vamos adicionar o serviço do ***`MVC`***. O método deverá ficar assim \n```c#\n public void ConfigureServices(IServiceCollection services)\n  {\n    services.AddControllersWithViews();\n  }\n```\n\nVamos adicionar a rota, método *Configure* vamos trocar \n```c#\napp.UseEndpoints(endpoints =\u003e\n{\n    endpoints.MapGet(\"/\", async context =\u003e\n    {\n      await context.Response.WriteAsync(\"Hello World!\");\n    });\n}); \n```\nPor \n```c#\napp.UseEndpoints(endpoints =\u003e\n {\n    endpoints.MapControllerRoute(\n    name: \"default\",\n    pattern: \"{controller=Home}/{action=Index}/{id?}\");\n  });\n```\nCom isso nosso arquivo ***Startup.cs*** ficará com código abaixo:\n\n```c#\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\n\nnamespace app_mvc\n{\n    public class Startup\n    {\n        // This method gets called by the runtime. Use this method to add services to the container.\n        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940\n        public void ConfigureServices(IServiceCollection services)\n        {\n            services.AddControllersWithViews();\n        }\n\n        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n            }\n\n            app.UseRouting();\n\n            app.UseEndpoints(endpoints =\u003e\n            {\n                endpoints.MapControllerRoute(\n                    name: \"default\",\n                    pattern: \"{controller=Home}/{action=Index}/{id?}\"\n                );\n            });\n        }\n    }\n}\n\n```\nVamos rodar novamente nossa aplicação digitando *`dotnet run`* no terminal e acessando o *link*: [`http://localhost:5000/`](http://localhost:5000/).\n\n![](screenshots/ss_3.png)\n\n*Glória a Deuuuuss???* :raised_hands:\n\n# Layouts\n\n### O que é um layout\n\nA maioria dos aplicativos Web tem um layout comum que fornece aos usuários uma experiência consistente durante sua navegação de uma página a outra. O layout normalmente inclui elementos comuns de interface do usuário, como o cabeçalho do aplicativo, elementos de menu ou de navegação e rodapé. [Por Steve Smith e Dave Brock](https://docs.microsoft.com/pt-br/aspnet/core/mvc/views/layout?view=aspnetcore-3.1).\n\n![](screenshots/page-layout.png)\n\nEstruturas HTML comuns, como scripts e folhas de estilo, também são usadas com frequência por muitas páginas em um aplicativo. Todos esses elementos compartilhados podem ser definidos em um arquivo de layout, que pode então ser referenciado por qualquer página usada no aplicativo. Os layouts reduzem o código duplicado nas página. Por convenção, o layout padrão de um aplicativo ASP.NET Core é chamado *`_Layout.cshtml`*, e segue o modelo abaixo:\n\n![](screenshots/ss_4.png)\n\n### Criando nossa *_Layout.cshtml*\n\nAgora vamos criar nossa *layout* e ficará dentro da pasta **Views \u003e Shared** e terá o código abaixo:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"utf-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" /\u003e\n    \u003ctitle\u003e@ViewData[\"Title\"] - app-mvc\u003c/title\u003e\n    \u003clink rel=\"stylesheet\" href=\"~/lib/bootstrap/dist/css/bootstrap.min.css\" /\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cheader\u003e\n        \u003cnav class=\"navbar navbar-expand-lg navbar-light bg-light\"\u003e\n                \u003ca class=\"navbar-brand\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\"\u003eapp-mvc\u003c/a\u003e\n                \u003cbutton class=\"navbar-toggler\" type=\"button\" data-toggle=\"collapse\" data-target=\".navbar-collapse\" aria-controls=\"navbarSupportedContent\"\n                        aria-expanded=\"false\" aria-label=\"Toggle navigation\"\u003e\n                    \u003cspan class=\"navbar-toggler-icon\"\u003e\u003c/span\u003e\n                \u003c/button\u003e\n                \u003cdiv class=\"navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse\"\u003e\n                    \u003cul class=\"navbar-nav flex-grow-1\"\u003e\n                        \u003cli class=\"nav-item\"\u003e\n                            \u003ca class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Index\"\u003eHome\u003c/a\u003e\n                        \u003c/li\u003e\n                        \u003cli class=\"nav-item\"\u003e\n                            \u003ca class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Home\" asp-action=\"Privacy\"\u003ePrivacy\u003c/a\u003e\n                        \u003c/li\u003e\n                    \u003c/ul\u003e\n                \u003c/div\u003e\n        \u003c/nav\u003e\n    \u003c/header\u003e\n    \u003cdiv class=\"container\"\u003e\n        \u003cmain role=\"main\" class=\"pb-3\"\u003e\n            @RenderBody()\n        \u003c/main\u003e\n    \u003c/div\u003e\n\n    \u003cfooter class=\"border-top footer text-muted\"\u003e\n        \u003cdiv class=\"container\"\u003e\n            \u0026copy; 2020 - app-mvc - \u003ca asp-area=\"\" asp-controller=\"Home\" asp-action=\"Privacy\"\u003ePrivacy\u003c/a\u003e\n        \u003c/div\u003e\n    \u003c/footer\u003e\n    \u003cscript src=\"~/lib/jquery/dist/jquery.min.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"~/lib/bootstrap/dist/js/bootstrap.bundle.min.js\"\u003e\u003c/script\u003e\n    @RenderSection(\"Scripts\", required: false)\n\u003c/body\u003e\n\u003c/html\u003e\n\n```\n \n## Especificando um layout - ViewStart.cshtml\n\nO mecanismo de exibição Razor no MVC possui uma convenção na qual ele procura qualquer arquivo com o nome *`_ViewStart.cshtml`* e executa o código dentro desse arquivo antes de executar o código em uma página individual esse arquivo normalmente é colocado diretamente na pasta **Views**.\n\nVamos criar nossa *`_ViewStart.cshtml`* na pasta **Views** com o código abaixo:\n\n```html\n@{\n    Layout = \"_Layout\";\n}\n```\n\nAo rodarmos nossa aplicação digitando *`dotnet run`* no terminal e acessando o *link*: [`http://localhost:5000/`](http://localhost:5000/), notamos que funcionou como o esperado.\n\n![](screenshots/ss_5.png)\n\n\n## Cascading Style Sheets - CSS\n\n***Cascading Style Sheets (CSS)*** que traduzido para o português, significa *`Folha de Estilo em Cascatas`* é um mecanismo para adicionar estilo (cores, fontes, espaçamento, etc.) a um documento web, deixando assim nossas páginas com as aparências mais atraentes.\n\n![](screenshots/css-x-cores-css-existente-como-dar-manutencao-1538334855.gif)\n\nAo invés de criarmos um arquivo *`css`* e customizarmos todas as *tags* uma por uma, podemos utilizar um [Framework](https://pt.wikipedia.org/wiki/Framework) que nos ajudará nessa missão, estou falando do [Bootstrap ](https://getbootstrap.com/) que é o framework mais utilizado para criar layouts e páginas de sistemas web, dashboards, sites responsivos e sites comuns, também. Ele facilita muito o trabalho de front-end.\n\n## Bootstrap no AspNetCore\n\nVou utilizar a versão 4.4 do *Bootstrap* e para fazer o *download* [clique aqui](https://getbootstrap.com/docs/4.4/getting-started/download/).\n\nPor convensão os arquivos externos ficam dentro da pasta ***wwwroot \u003e lib \u003e {biblioteca/framework} \u003e dist*** \n\u003e * Em nosso caso substituiremos `{biblioteca/framework}` por `bootstrap` \n\nNossa estrutura ficará assim:\n\u003e css\n\u003e * *`wwwroot \u003e lib \u003e bootstrap \u003e dist \u003e css`*\n\u003e\u003e  Vamos adicionar na pasta `css` apenas o arquivo ***bootstrap.min.css***\n\n\u003e js\n\u003e * *`wwwroot \u003e lib \u003e bootstrap \u003e dist \u003e js`*\n\u003e\u003e E na pasta `js` adicionaremos apenas o arquivo ***bootstrap.bundle.min.js***\n\nPara que as funcionalidades do arquivo ***bootstrap.bundle.min.js*** executem sem maiores problemas precisaremos incluir também a biblioteca `JavaScript` [jQuery](https://jquery.com/).\n\u003e Temos que criar a pasta **jquery** em ***wwwroot \u003e lib***\n\n para fazer o download da versão 3.4.1 [clique aqui](https://code.jquery.com/jquery-3.4.1.min.js) e salve em: \n \u003e*`wwwroot \u003e lib \u003e jquery \u003e dist`* com o nome ***jquery.min.js***\n\n As estruturas de pastas devem ficar assim:\n\n ![](screenshots/ss_6.png)\n\n Ao rodarmos nossa aplicação digitando *`dotnet run`* no terminal e acessando o *link*: [`http://localhost:5000/`](http://localhost:5000/), notamos que nada aconteceu:\n##\n  ![](screenshots/ss_7.png)\n##\n  Com o nosso navegador aberto em [`http://localhost:5000/`](http://localhost:5000/), clicando com o botão direto do mouse em *`Inspecionar`* e depois na *aba* *`Console`* percebemos que temos o erro  **404 - not found** ou seja *não encontrado*:\n##\n  ![](screenshots/ss_8.png)\n##\n  Precisamos *\"dizer\"* para o ***dotnet*** que queremos usar `arquivos estáticos`. Para isso vamos abrir nosso arquivo ***Startup.cs*** e no método  *Configure* vamos adicionar a configuração `app.UseStaticFiles();`.\n  \n  O método  *Configure*  ficará da seguinte forma:\n\n  ```c#\n  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n   {\n     if (env.IsDevelopment())    \n      {\n       app.UseDeveloperExceptionPage();\n      }\n\n     app.UseRouting();\n     app.UseStaticFiles();\n\n     app.UseEndpoints(endpoints =\u003e\n      {\n        endpoints.MapControllerRoute(\n        name: \"default\",\n        pattern: \"{controller=Home}/{action=Index}/{id?}\");\n     });\n    }\n  ```\n  Vamos rodar nossa aplicação digitando *`dotnet run`* no terminal e acessando o *link*: [`http://localhost:5000/`](http://localhost:5000/). O resultado é fantástico! :muscle::sunglasses:\n\n \n![](screenshots/ss_9.png)\n\n\n# TagHelpers\n\nPerceba que se tentarmos navegar clicando nos *links* no nosso menu nada acontece, para isso precisamos utilizar as  ***`TagHelpers`***.\n\nAs ***TagHelpers*** são componentes reutilizáveis para automatizar a geração de HTML na Razor Pages, e não estão disponíveis para a página por padrão, são ativados adicionando uma diretiva *`@addTagHelper`* à página ou, geralmente, a um arquivo   ***_ViewImports.cshtml***.\n\n### Habilitando TagHelpers\n\nVamos criar nossa *`_ViewImports.cshtml`* na pasta **Views** com o código abaixo:\n\n```html\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n```\nA diretiva *`@addTagHelper`* é seguida por um caractere `(*)` para especificar que todas *TagHelper* encontrados no assembly especificado devem ser usados e, em seguida, é fornecido o nome do assembly que contém as *TagHelper*.\n\u003e `Microsoft.AspNetCore.Mvc.TagHelpers` é o assembly que contém  ***TagHelper***.\n\nPara saber mais, acesse a documentação oficial [clicando aqui](https://docs.microsoft.com/pt-br/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-3.1).\n\n# Models\n\n### O que é Model? \nSegundo o [Portal GSTI](https://www.portalgsti.com.br/2017/08/padrao-mvc-arquitetura-model-view-controller.html):\n* É responsável pela comunicação com o banco de dados.\n* É a camada que contém a estrutura de dado atrás de uma parte específica da aplicação.\n* Responsável pela leitura manipulação e validação de dados, e também de suas validações.\n* Responsável por tratar as regras de negócio. \n* Obtém os dados e os traduz em informações relevantes para serem exibidas pela View.\n* Notifica a view e controler associados quando há uma mudança em seu estado.\n\n## Criando Model *Aluno*\n\nA Model ***Aluno*** não seguirá nenhum `Padrão de Projeto`*`(Design Patterns)`* pois se tratado de um exemplo de nível **básico**. Porém, se tem interresse em saber mais, recomendo:\n* [eBook de Design Patterns](https://www.fabiosilvalima.net/design-patterns-vol-1/) `FREE`\n* [Use a Cabeça! Padrões de Projetos](https://www.amazon.com.br/Cabe%C3%A7a-Padr%C3%B5es-Projetos-Eric-Freeman/dp/8576081741/ref=sr_1_1?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91\u0026keywords=Use+a+Cabe%C3%A7a%21+Padr%C3%B5es+de+Projetos\u0026qid=1579186619\u0026s=books\u0026sr=1-1) `PAGO`\n\nAgora ***mão no código***, primeiramente criaremos uma *controller* ***`AlunoController.cs`*** na pasta **Controllers**. Incluíremos um *método* publico do tipo `IActionResult` com o nome **Index** que retornará todos os alunos cadastrados.\n```c#\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace app_mvc.Controllers\n{\n    public class AlunoController : Controller\n    {\n        // GET: Alunos\n        public IActionResult Index()\n        {\n            \n            return View();\n        }\n    }\n}\n```\n### Model *Aluno*\n\n**Models** nada mais é do um classe, com isso em mente criaremos nossa `classe` ***Aluno.cs*** na pasta **Models** que seguirá o [diagrama de classe](https://pt.wikipedia.org/wiki/Diagrama_de_classes) abaixo:\n\n![](screenshots/ss_10.png)\n\nO Código:\n\n```c#\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace app_mvc.Models\n{\n    public class Aluno\n    {\n        public int Id { get; set; }\n        public string Nome { get; set; }    \n        public int Idade { get; set; }\n        public char Genero { get; set; }\n        public string Curso { get; set; }\n        private List\u003cAluno\u003e _listaAluno;\n    }\n}\n```\n\nComo não farei uma comunicação com o *Banco de Dados*, vou criar o *método* ***CriarAluno*** manualmente.\n```c#\npublic void CriarAluno()\n{\n  try\n  {\n    _listaAluno = new List\u003cAluno\u003e()\n    {\n        new Aluno(){ Id = 1,Nome= \"Paulo\",Idade=29, Genero = 'M', Curso=\"Ciência da Computação\"},\n        new Aluno(){ Id = 2,Nome= \"Alexandre\",Idade=20, Genero = 'M', Curso=\"Economia\"},\n        new Aluno(){ Id = 3,Nome= \"Carlos\",Idade=25, Genero = 'M', Curso=\"Ciências Contábeis\"},\n        new Aluno(){ Id = 4,Nome= \"Bianca\",Idade=25, Genero = 'F', Curso=\"Ciência da Computação\"},\n        new Aluno(){ Id = 5,Nome= \"Laura\",Idade=35, Genero = 'F', Curso=\"Literatura\"}\n    };\n   }\n    catch (System.Exception ex)\n    {\n          \n        throw new Exception(ex.Message);\n    }\n}\n```\n\u003e Destacando que pelo `Design Patterns` deveriamos ter uma `Classe` que implementaria uma `Interface` de ***Aluno***.\n\nCriaremos o *método* **BuscarAluno** na *Classe* **Aluno** que retorna uma *`lista de Aluno`*:\n```c#\npublic List\u003cAluno\u003e BuscarAluno()\n{\n    try\n    {\n     return _listaAluno;\n    }\n    catch (System.Exception ex)\n    {\n     throw new Exception(ex.Message);\n    }\n}\n``` \n\n**Maravilha!!!** :ok_hand:\n\nVoltando para *Controller* **AlunoController.cs** no método ***Index*** vamos fazer com que esse método use nossa *Model* **Aluno**.\nPrimeiro use a diretiva `using app_mvc.Models;` e depois altere o método **Index** para o código abaixo:\n```c#\n// GET: Alunos\npublic IActionResult Index()\n{\n    Aluno _aluno = new Aluno();  \n    _aluno.CriarAluno();\n\n    return View(_aluno.BuscarAluno());\n}\n```\n\u003e Mais uma recomendação do `Design Patterns` para nosso código acima seria usar [Injeção de Dependência](https://www.devmedia.com.br/design-patterns-injecao-de-dependencia-com-csharp/23671).\n\n## Criando a View *Index* do *AlunoController*\n\nCriaremos a ***Index.cshtml*** dentro da *pasta* ***Views \u003e Aluno*** como o código abaixo:\n\n```html\n@model IEnumerable\u003capp_mvc.Models.Aluno\u003e\n\n@{\n    ViewData[\"Title\"] = \"Aluno\";\n}\n\n\u003cdiv class=\"jumbotron jumbotron-fluid text-center\"\u003e\n  \u003cdiv class=\"container\"\u003e\n    \u003ch1 class=\"display-4\"\u003eAluno\u003c/h1\u003e\n    \u003cp class=\"lead\"\u003eAqui vemos o resultado da implementação da \u003ci\u003eModel\u003c/i\u003e \u003cstrong\u003eAluno\u003c/strong\u003e.\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cdiv class=\"container\"\u003e\n    \u003ctable class=\"table table-striped\"\u003e\n  \u003cthead class=\"thead-dark\"\u003e\n    \u003ctr\u003e\n      \u003cth scope=\"col\"\u003eCódigo\u003c/th\u003e\n      \u003cth scope=\"col\"\u003eNome\u003c/th\u003e\n      \u003cth scope=\"col\"\u003eIdade\u003c/th\u003e\n      \u003cth scope=\"col\"\u003eSexo\u003c/th\u003e\n      \u003cth scope=\"col\"\u003eCurso\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      @foreach (var aluno in Model)\n      {\n        \u003ctr\u003e\n            \u003ctd\u003e@aluno.Id\u003c/td\u003e\n            \u003ctd\u003e@aluno.Nome\u003c/td\u003e\n            \u003ctd\u003e@aluno.Idade\u003c/td\u003e\n            \u003ctd\u003e@aluno.Genero\u003c/td\u003e\n            \u003ctd\u003e@aluno.Curso\u003c/td\u003e\n        \u003c/tr\u003e\n      }\n   \n  \u003c/tbody\u003e\n    \u003c/table\u003e\n\u003c/div\u003e\n```\n### Adicionando um link na *Layout*\n\nAdicionaremos uma *ação* para que possamos acessar a nossa página. Na ***_Layout.cshtml*** modificaremos o código que direciona para a **View** ***`Privacy`*** que não estamos usando. O código ficará assim:\n\n```html\n \u003cli class=\"nav-item\"\u003e\n    \u003ca class=\"nav-link text-dark\" asp-area=\"\" asp-controller=\"Aluno\" asp-action=\"Index\"\u003eAluno\u003c/a\u003e\n \u003c/li\u003e\n```\n\n## Resultado Final\n\n![](screenshots/ss_11.png)\n\n\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphjb%2Fapp-mvc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphjb%2Fapp-mvc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphjb%2Fapp-mvc/lists"}