From d6110f68fba621609e5e452437427a5bbb7f0f64 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:40:04 -0300 Subject: [PATCH 01/35] feat: add file gitignore --- ApiDotNetFramework/.gitignore | 398 ++++++++++++++++++++++++++++++++++ 1 file changed, 398 insertions(+) create mode 100644 ApiDotNetFramework/.gitignore diff --git a/ApiDotNetFramework/.gitignore b/ApiDotNetFramework/.gitignore new file mode 100644 index 0000000..8a30d25 --- /dev/null +++ b/ApiDotNetFramework/.gitignore @@ -0,0 +1,398 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml From e90aa0d40036a5de04bfaa6012cb746f9cd489cc Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:40:30 -0300 Subject: [PATCH 02/35] feat: create file docker-compose sql server database --- ApiDotNetFramework/docker-compose.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 ApiDotNetFramework/docker-compose.yml diff --git a/ApiDotNetFramework/docker-compose.yml b/ApiDotNetFramework/docker-compose.yml new file mode 100644 index 0000000..f6e7fe7 --- /dev/null +++ b/ApiDotNetFramework/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3' +services: + sqlserver: + image: mcr.microsoft.com/mssql/server + container_name: SQLSERVER + environment: + - ACCEPT_EULA=Y + - SA_PASSWORD=1q2w3e4r@ + ports: + - "1433:1433" + volumes: + - .\Database:/var/opt/mssql/data From 6a7e4ee4780d86cd280547e29faf918b7b4eaba8 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:41:02 -0300 Subject: [PATCH 03/35] feat: alter config files --- .../ApiDotNetFramework/Web.Debug.config | 12 ++++ .../ApiDotNetFramework/Web.Release.config | 31 +++++++++ .../ApiDotNetFramework/Web.config | 66 +++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Web.Debug.config create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Web.Release.config create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Web.config diff --git a/ApiDotNetFramework/ApiDotNetFramework/Web.Debug.config b/ApiDotNetFramework/ApiDotNetFramework/Web.Debug.config new file mode 100644 index 0000000..c19fe7c --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Web.Debug.config @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/ApiDotNetFramework/ApiDotNetFramework/Web.Release.config b/ApiDotNetFramework/ApiDotNetFramework/Web.Release.config new file mode 100644 index 0000000..c358444 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/ApiDotNetFramework/ApiDotNetFramework/Web.config b/ApiDotNetFramework/ApiDotNetFramework/Web.config new file mode 100644 index 0000000..79f4c07 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Web.config @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 6d0d10b11d3e24870250d51e13f142f46a92ca1c Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:41:24 -0300 Subject: [PATCH 04/35] feat: create result view model --- .../ViewModels/ResultViewModel.cs | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework/ViewModels/ResultViewModel.cs diff --git a/ApiDotNetFramework/ApiDotNetFramework/ViewModels/ResultViewModel.cs b/ApiDotNetFramework/ApiDotNetFramework/ViewModels/ResultViewModel.cs new file mode 100644 index 0000000..0ef764a --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/ViewModels/ResultViewModel.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace ApiDotNetFramework.ViewModels +{ + public class ResultViewModel + { + public ResultViewModel(T data, List errors) + { + Data = data; + Errors = errors; + } + + public ResultViewModel(T data) + { + Data = data; + + } + + public ResultViewModel(List errors) + { + Errors = errors; + } + + public ResultViewModel(string error) + { + Errors.Add(error); + } + + + + public T Data { get; private set; } + + public List Errors { get; private set; } = new List(); + } +} \ No newline at end of file From 14b54f5cedd20845e76a19d8fdeecd3659c24685 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:41:55 -0300 Subject: [PATCH 05/35] feat: create interface repository --- .../ApiDotNetFramework/Interfaces/IRepository.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Interfaces/IRepository.cs diff --git a/ApiDotNetFramework/ApiDotNetFramework/Interfaces/IRepository.cs b/ApiDotNetFramework/ApiDotNetFramework/Interfaces/IRepository.cs new file mode 100644 index 0000000..e62650e --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Interfaces/IRepository.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace ApiDotNetFramework.Interfaces +{ + public interface IRepository where TEntity : class + { + List GetAll(); + TEntity GetById(TKey id); + int Insert(TEntity entity); + void Update(TEntity entity, TKey id); + void Delete(TKey id); + } +} From 99f1b3a513e4bf3e398b74cf17256097e04c97e5 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:42:31 -0300 Subject: [PATCH 06/35] feat: create product entity --- .../Entities/ProductEntity.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Entities/ProductEntity.cs diff --git a/ApiDotNetFramework/ApiDotNetFramework/Entities/ProductEntity.cs b/ApiDotNetFramework/ApiDotNetFramework/Entities/ProductEntity.cs new file mode 100644 index 0000000..a274bc0 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Entities/ProductEntity.cs @@ -0,0 +1,30 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace ApiDotNetFramework.Entities +{ + public class ProductEntity + { + public int Id { get; set; } + [Required(ErrorMessage = "the field name missing.")] + public string Name { get; set; } + public string Brand { get; set; } + [Required(ErrorMessage = "the filed price missing.")] + public double Price { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + + public ProductEntity() + { + + } + + public ProductEntity(string name, string brand, double price) + { + Name = name; + Brand = brand; + Price = price; + } + + } +} \ No newline at end of file From 36caac2ac637e4d0a1ca9d1107c3860d15cb3e2d Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:42:57 -0300 Subject: [PATCH 07/35] feat: create sql server repository --- .../Repositories/SqlServerRepository.cs | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Repositories/SqlServerRepository.cs diff --git a/ApiDotNetFramework/ApiDotNetFramework/Repositories/SqlServerRepository.cs b/ApiDotNetFramework/ApiDotNetFramework/Repositories/SqlServerRepository.cs new file mode 100644 index 0000000..fe86560 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Repositories/SqlServerRepository.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections.Generic; +using ApiDotNetFramework.Interfaces; +using System.Web.Configuration; +using ApiDotNetFramework.Entities; +using System.Data.SqlClient; +using System.Data; +using System.Configuration; + +namespace ApiDotNetFramework.Repositories +{ + public class SqlServerRepository : IRepository + { + protected string stringConnection; + public SqlServerRepository() + { + stringConnection = ConfigurationManager.ConnectionStrings["DatabaseConnection"].ConnectionString; + } + + public List GetAll() + { + using (var conn = new SqlConnection(stringConnection)) + { + List listaProdutos = new List(); + ProductEntity produto = null; + try + { + SqlCommand cmd = new SqlCommand("sp_select_products", conn); + cmd.CommandType = CommandType.StoredProcedure; + conn.Open(); + using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) + { + while (reader.Read()) + { + produto = new ProductEntity() + { + CreatedAt = (DateTime)reader["createdAt"], + Name = reader["name"].ToString(), + Price = (double)reader["price"], + Brand = reader["brand"].ToString(), + UpdatedAt = (DateTime?)reader["updatedAt"], + Id = (int)reader["id"], + }; + listaProdutos.Add(produto); + } + } + } + catch (Exception error) + { + throw error; + } + return listaProdutos; + } + } + + public ProductEntity GetById(int id) + { + using (var conn = new SqlConnection(stringConnection)) + { + ProductEntity produto = null; + try + { + SqlCommand cmd = new SqlCommand("sp_select_products", conn); + cmd.CommandType = CommandType.StoredProcedure; + conn.Open(); + cmd.Parameters.AddWithValue("@id", id); + using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) + { + while (reader.Read()) + { + produto = new ProductEntity() + { + CreatedAt = (DateTime)reader["createdAt"], + Name = reader["name"].ToString(), + Price = (double)reader["price"], + Brand = reader["brand"].ToString(), + UpdatedAt = (DateTime?)reader["updatedAt"], + Id = (int)reader["id"], + }; + } + } + } + catch (Exception error) + { + throw error; + } + return produto; + } + } + + public int Insert(ProductEntity entity) + { + using (var conn = new SqlConnection(stringConnection)) + { + try + { + var cmd = new SqlCommand("sp_insert_products", conn); + conn.Open(); + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.AddWithValue("@name", entity.Name); + cmd.Parameters.AddWithValue("@brand", entity.Brand); + cmd.Parameters.AddWithValue("@price", entity.Price); + + SqlParameter id = new SqlParameter(); + id.ParameterName = "@id"; + id.Direction = ParameterDirection.Output; + id.SqlDbType = SqlDbType.Int; + cmd.Parameters.Add(id); + + cmd.ExecuteNonQuery(); + + return (int)id.Value; + } + catch (Exception error) + { + + throw error; + } + + } + } + + public void Update(ProductEntity entity, int id) + { + using (var conn = new SqlConnection(stringConnection)) + { + try + { + var cmd = new SqlCommand("sp_update_products", conn); + conn.Open(); + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.AddWithValue("@id", id); + cmd.Parameters.AddWithValue("@name", entity.Name); + cmd.Parameters.AddWithValue("@brand", entity.Brand); + cmd.Parameters.AddWithValue("@price", entity.Price); + cmd.ExecuteNonQuery(); + + } + catch (Exception error) + { + throw error; + } + + } + } + + public void Delete(int id) + { + using (var conn = new SqlConnection(stringConnection)) + { + try + { + var cmd = new SqlCommand("sp_delete_products", conn); + conn.Open(); + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.AddWithValue("@id", id); + cmd.ExecuteNonQuery(); + } + catch (Exception error) + { + throw error; + } + + } + } + + } +} \ No newline at end of file From 821af480b30f23a6b07a28c7d9c112d754fb6505 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:43:09 -0300 Subject: [PATCH 08/35] feat: create fake repository --- .../Repositories/FakeRepository.cs | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Repositories/FakeRepository.cs diff --git a/ApiDotNetFramework/ApiDotNetFramework/Repositories/FakeRepository.cs b/ApiDotNetFramework/ApiDotNetFramework/Repositories/FakeRepository.cs new file mode 100644 index 0000000..14edcc1 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Repositories/FakeRepository.cs @@ -0,0 +1,74 @@ +using ApiDotNetFramework.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace ApiDotNetFramework.Repositories +{ + public class FakeRepository + { + public List listaProdutos; + + public FakeRepository() + { + listaProdutos = new List(); + listaProdutos.Add(new ProductEntity() { Id = 1, Name = "Product01", Brand = "Brand01", Price = 2.0 }); + listaProdutos.Add(new ProductEntity() { Id = 2, Name = "Product02", Brand = "Brand02", Price = 2.5 }); + listaProdutos.Add(new ProductEntity() { Id = 3, Name = "Product03", Brand = "Brand03", Price = 1.2 }); + listaProdutos.Add(new ProductEntity() { Id = 4, Name = "Product04", Brand = "Brand04", Price = 7.7 }); + listaProdutos.Add(new ProductEntity() { Id = 5, Name = "Product05", Brand = "Brand05", Price = 4.3 }); + listaProdutos.Add(new ProductEntity() { Id = 6, Name = "Product06", Brand = "Brand06", Price = 5.1 }); + } + + public List GetAll() + { + return listaProdutos; + } + + public ProductEntity GetById(int id) + { + return listaProdutos.FirstOrDefault(x => x.Id == id); + } + + public int Insert(ProductEntity entity) + { + var maxId = listaProdutos.Max(t => t.Id); + maxId++; + + var produto = new ProductEntity(){ + Id = maxId, + Name = entity.Name, + Brand = entity.Brand, + Price = entity.Price, + CreatedAt = DateTime.Now + }; + listaProdutos.Add(produto); + return maxId; + } + + public void Update(ProductEntity entity, int id) + { + var index = listaProdutos.FindIndex(t => t.Id == id); + + if (index != null) + { + listaProdutos[index].Name = entity.Name; + listaProdutos[index].Brand = entity.Brand; + listaProdutos[index].Price = entity.Price; + listaProdutos[index].UpdatedAt = DateTime.Now; + } + } + + public void Delete(int id) + { + var index = listaProdutos.FindIndex(t => t.Id == id); + + if (index != null) + { + listaProdutos.RemoveAt(index); + + } + } + } +} \ No newline at end of file From 67b98c61b717088510ed2fc419f2fbf56e1a4646 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:43:22 -0300 Subject: [PATCH 09/35] feat: create product controller --- .../Controllers/ProductController.cs | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Controllers/ProductController.cs diff --git a/ApiDotNetFramework/ApiDotNetFramework/Controllers/ProductController.cs b/ApiDotNetFramework/ApiDotNetFramework/Controllers/ProductController.cs new file mode 100644 index 0000000..cb1fa05 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Controllers/ProductController.cs @@ -0,0 +1,118 @@ +using ApiDotNetFramework.Entities; +using ApiDotNetFramework.Repositories; +using ApiDotNetFramework.ViewModels; +using System; +using System.Net; +using System.Net.Http; +using System.Web.Http; + +namespace ApiDotNetFramework.Controllers +{ + public class ProductController : ApiController + { + private SqlServerRepository respository = new SqlServerRepository(); + + [HttpGet] + [Route("api/v1/products")] + public HttpResponseMessage Get() + { + try + { + var data = respository.GetAll(); + return Request.CreateResponse(HttpStatusCode.OK, new ResultViewModel(data)); + } + catch + { + return Request.CreateResponse(HttpStatusCode.InternalServerError, "Internal server error"); + } + } + + [HttpGet] + [Route("api/v1/products/{productId}")] + public HttpResponseMessage GetById( + [FromUri] int productId) + { + try + { + var data = respository.GetById(productId); + return Request.CreateResponse(HttpStatusCode.OK, new ResultViewModel(data)); + } + catch + { + return Request.CreateResponse(HttpStatusCode.InternalServerError, "Internal server error"); + } + } + + + [HttpPost] + [Route("api/v1/products")] + public HttpResponseMessage Post(ProductEntity product) + { + + if (!ModelState.IsValid) + return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); + try + { + var id = respository.Insert(product); + product.Id = id; + product.CreatedAt = DateTime.Now; + return Request.CreateResponse(HttpStatusCode.Created, new ResultViewModel(product)); + } + catch (Exception) + { + return Request.CreateResponse(HttpStatusCode.InternalServerError, "Error to create product. "); + } + } + + [HttpPut] + [Route("api/v1/products/{productId}")] + public HttpResponseMessage Put( + ProductEntity product, + [FromUri] int productId) + { + + if (!ModelState.IsValid) + return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); + try + { + var data = respository.GetById(productId); + if (data == null) + return Request.CreateResponse(HttpStatusCode.NoContent, new ResultViewModel(data)); + + data.Name = product.Name; + data.Brand = product.Brand; + data.Price = product.Price; + data.UpdatedAt = DateTime.Now; + respository.Update(data, productId); + + return Request.CreateResponse(HttpStatusCode.OK, new ResultViewModel(data)); + } + catch (Exception) + { + return Request.CreateResponse(HttpStatusCode.InternalServerError, "Error to update product. "); + } + } + + + [HttpDelete] + [Route("api/v1/products/{productId}")] + public HttpResponseMessage Delete( + [FromUri] int productId) + { + try + { + var data = respository.GetById(productId); + if(data == null) + return Request.CreateResponse(HttpStatusCode.NoContent, new ResultViewModel(data)); + + respository.Delete(productId); + return Request.CreateResponse(HttpStatusCode.OK, new ResultViewModel("")); + } + catch (Exception) + { + return Request.CreateResponse(HttpStatusCode.InternalServerError, "Error to update product. "); + } + } + + } +} \ No newline at end of file From 0b590a5ce5133bc72e0b8eeaa3b6a0336d0b1a60 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:43:48 -0300 Subject: [PATCH 10/35] test: create product tests --- .../ApiDotNetFramework.Tests/ProductTest.cs | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework.Tests/ProductTest.cs diff --git a/ApiDotNetFramework/ApiDotNetFramework.Tests/ProductTest.cs b/ApiDotNetFramework/ApiDotNetFramework.Tests/ProductTest.cs new file mode 100644 index 0000000..404c808 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework.Tests/ProductTest.cs @@ -0,0 +1,81 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ApiDotNetFramework.Entities; +using ApiDotNetFramework.Repositories; + +namespace ApiDotNetFramework.Tests +{ + [TestClass] + public class ProductTest + { + [TestMethod] + [TestCategory("Product")] + public void Should_Create_Valid_Product() + { + var product = new ProductEntity("Test", "Test", 7.5); + Assert.AreEqual(product.Name, "Test"); + Assert.AreEqual(product.Brand, "Test"); + Assert.AreEqual(product.Price, 7.5); + } + + + [TestMethod] + [TestCategory("Product")] + public void Should_Get_All_Products() + { + var repository = new FakeRepository(); + var listaProdutos = repository.GetAll(); + Assert.AreEqual(listaProdutos.Count,6); + } + + [TestMethod] + [TestCategory("Product")] + public void Should_Get_Product_ById() + { + var repository = new FakeRepository(); + var produto = repository.GetById(2); + Assert.AreEqual(produto.Id, 2); + Assert.AreEqual(produto.Name, "Product02"); + Assert.AreEqual(produto.Brand, "Brand02"); + Assert.AreEqual(produto.Price, 2.5); + } + + + [TestMethod] + [TestCategory("Product")] + public void Should_Insert_New_Product() + { + var repository = new FakeRepository(); + var totalProducts = repository.listaProdutos.Count; + var Id = totalProducts + 1; + var product = new ProductEntity() {Name = "Product" + Id, Brand = "Brand" + Id, Price = 4.99 }; + repository.Insert(product); + Assert.IsTrue(repository.listaProdutos.Count > totalProducts); + } + + [TestMethod] + [TestCategory("Product")] + public void Should_Update_Product() + { + var repository = new FakeRepository(); + var totalProducts = repository.listaProdutos.Count; + var Id = 3; + var product = new ProductEntity() { Name = "ProductUpdated", Brand = "BrandUpdated", Price = 9.99 }; + repository.Update(product, Id); + var Index = repository.listaProdutos.FindIndex(x => x.Id == Id); + Assert.IsTrue(repository.listaProdutos[Index].Name == "ProductUpdated"); + Assert.IsTrue(repository.listaProdutos[Index].Brand == "BrandUpdated"); + Assert.IsTrue(repository.listaProdutos[Index].Price == 9.99); + } + + [TestMethod] + [TestCategory("Product")] + public void Should_Delete_Product() + { + var repository = new FakeRepository(); + var totalProducts = repository.listaProdutos.Count; + repository.Delete(2); + Assert.IsTrue(repository.listaProdutos.Count < totalProducts); + } + } +} From 5ec33116310590abf05b0f79fb3be28ad104b9c0 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:44:11 -0300 Subject: [PATCH 11/35] feat: crete files project --- .../ApiDotNetFramework.Tests.csproj | 69 +++++++ .../Properties/AssemblyInfo.cs | 36 ++++ ApiDotNetFramework/ApiDotNetFramework.sln | 30 +++ .../ApiDotNetFramework.csproj | 180 ++++++++++++++++++ .../App_Start/WebApiConfig.cs | 24 +++ .../ApplicationInsights.config | 84 ++++++++ .../ApiDotNetFramework/Global.asax | 1 + .../ApiDotNetFramework/Global.asax.cs | 17 ++ .../Properties/AssemblyInfo.cs | 35 ++++ .../ApiDotNetFramework/packages.config | 18 ++ 10 files changed, 494 insertions(+) create mode 100644 ApiDotNetFramework/ApiDotNetFramework.Tests/ApiDotNetFramework.Tests.csproj create mode 100644 ApiDotNetFramework/ApiDotNetFramework.Tests/Properties/AssemblyInfo.cs create mode 100644 ApiDotNetFramework/ApiDotNetFramework.sln create mode 100644 ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj create mode 100644 ApiDotNetFramework/ApiDotNetFramework/App_Start/WebApiConfig.cs create mode 100644 ApiDotNetFramework/ApiDotNetFramework/ApplicationInsights.config create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Global.asax create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Global.asax.cs create mode 100644 ApiDotNetFramework/ApiDotNetFramework/Properties/AssemblyInfo.cs create mode 100644 ApiDotNetFramework/ApiDotNetFramework/packages.config diff --git a/ApiDotNetFramework/ApiDotNetFramework.Tests/ApiDotNetFramework.Tests.csproj b/ApiDotNetFramework/ApiDotNetFramework.Tests/ApiDotNetFramework.Tests.csproj new file mode 100644 index 0000000..40a0b11 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework.Tests/ApiDotNetFramework.Tests.csproj @@ -0,0 +1,69 @@ + + + + Debug + AnyCPU + {939D1ED1-8075-45EC-BA70-067AA23339DD} + Library + Properties + ApiDotNetFramework.Tests + ApiDotNetFramework.Tests + v4.5.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + False + UnitTest + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + {F9D9CCC3-632A-46A0-957B-68794F4F218A} + ApiDotNetFramework + + + + + + \ No newline at end of file diff --git a/ApiDotNetFramework/ApiDotNetFramework.Tests/Properties/AssemblyInfo.cs b/ApiDotNetFramework/ApiDotNetFramework.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..766594d --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ApiDotNetFramework.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ApiDotNetFramework.Tests")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("939d1ed1-8075-45ec-ba70-067aa23339dd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ApiDotNetFramework/ApiDotNetFramework.sln b/ApiDotNetFramework/ApiDotNetFramework.sln new file mode 100644 index 0000000..41f2f3a --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDotNetFramework", "ApiDotNetFramework\ApiDotNetFramework.csproj", "{F9D9CCC3-632A-46A0-957B-68794F4F218A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDotNetFramework.Tests", "ApiDotNetFramework.Tests\ApiDotNetFramework.Tests.csproj", "{939D1ED1-8075-45EC-BA70-067AA23339DD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Database", "Database", "{61FA303C-C290-4F9C-88C5-FE8A5CC169D7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F9D9CCC3-632A-46A0-957B-68794F4F218A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9D9CCC3-632A-46A0-957B-68794F4F218A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9D9CCC3-632A-46A0-957B-68794F4F218A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9D9CCC3-632A-46A0-957B-68794F4F218A}.Release|Any CPU.Build.0 = Release|Any CPU + {939D1ED1-8075-45EC-BA70-067AA23339DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {939D1ED1-8075-45EC-BA70-067AA23339DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {939D1ED1-8075-45EC-BA70-067AA23339DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {939D1ED1-8075-45EC-BA70-067AA23339DD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj b/ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj new file mode 100644 index 0000000..4721915 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj @@ -0,0 +1,180 @@ + + + + + + + Debug + AnyCPU + + + 2.0 + {F9D9CCC3-632A-46A0-957B-68794F4F218A} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + ApiDotNetFramework + ApiDotNetFramework + v4.5.2 + true + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + ..\packages\Microsoft.ApplicationInsights.Agent.Intercept.1.2.1\lib\net45\Microsoft.AI.Agent.Intercept.dll + True + + + ..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.0.0\lib\net45\Microsoft.AI.DependencyCollector.dll + True + + + ..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.0.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll + True + + + ..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.0.0\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll + True + + + ..\packages\Microsoft.ApplicationInsights.Web.2.0.0\lib\net45\Microsoft.AI.Web.dll + True + + + ..\packages\Microsoft.ApplicationInsights.WindowsServer.2.0.0\lib\net45\Microsoft.AI.WindowsServer.dll + True + + + ..\packages\Microsoft.ApplicationInsights.2.0.0\lib\net45\Microsoft.ApplicationInsights.dll + True + + + ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + True + + + + + + + + + + + + + + + + + + + + + + + ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + + + + + + + + + + + + Global.asax + + + + + + + + + + + PreserveNewest + + + Web.config + + + Web.config + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 53455 + / + http://localhost:53455/ + False + False + + + False + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/ApiDotNetFramework/ApiDotNetFramework/App_Start/WebApiConfig.cs b/ApiDotNetFramework/ApiDotNetFramework/App_Start/WebApiConfig.cs new file mode 100644 index 0000000..592ada7 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/App_Start/WebApiConfig.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; + +namespace ApiDotNetFramework +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + // Web API configuration and services + + // Web API routes + config.MapHttpAttributeRoutes(); + + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional } + ); + } + } +} diff --git a/ApiDotNetFramework/ApiDotNetFramework/ApplicationInsights.config b/ApiDotNetFramework/ApiDotNetFramework/ApplicationInsights.config new file mode 100644 index 0000000..ee9ea3c --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/ApplicationInsights.config @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + System.Web.Handlers.TransferRequestHandler + Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler + System.Web.StaticFileHandler + System.Web.Handlers.AssemblyResourceLoader + System.Web.Optimization.BundleHandler + System.Web.Script.Services.ScriptHandlerFactory + System.Web.Handlers.TraceHandler + System.Web.Services.Discovery.DiscoveryRequestHandler + System.Web.HttpDebugHandler + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ApiDotNetFramework/ApiDotNetFramework/Global.asax b/ApiDotNetFramework/ApiDotNetFramework/Global.asax new file mode 100644 index 0000000..357e9cf --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="ApiDotNetFramework.WebApiApplication" Language="C#" %> diff --git a/ApiDotNetFramework/ApiDotNetFramework/Global.asax.cs b/ApiDotNetFramework/ApiDotNetFramework/Global.asax.cs new file mode 100644 index 0000000..71c1be1 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Global.asax.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Http; +using System.Web.Routing; + +namespace ApiDotNetFramework +{ + public class WebApiApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + GlobalConfiguration.Configure(WebApiConfig.Register); + } + } +} diff --git a/ApiDotNetFramework/ApiDotNetFramework/Properties/AssemblyInfo.cs b/ApiDotNetFramework/ApiDotNetFramework/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..35d0180 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ApiDotNetFramework")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ApiDotNetFramework")] +[assembly: AssemblyCopyright("Copyright © 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f9d9ccc3-632a-46a0-957b-68794f4f218a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ApiDotNetFramework/ApiDotNetFramework/packages.config b/ApiDotNetFramework/ApiDotNetFramework/packages.config new file mode 100644 index 0000000..54dcd93 --- /dev/null +++ b/ApiDotNetFramework/ApiDotNetFramework/packages.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file From f33540ee432941cea29cc1d9713010b1e13f0fbd Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:47:29 -0300 Subject: [PATCH 12/35] feat: create project api .net core --- ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo | Bin 0 -> 10752 bytes ApiDotNetCore/ApiDotNetCore.sln | 25 +++++++++++++ .../ApiDotNetCore/ApiDotNetCore.csproj | 13 +++++++ .../Controllers/WeatherForecastController.cs | 33 ++++++++++++++++++ ApiDotNetCore/ApiDotNetCore/Program.cs | 25 +++++++++++++ .../Properties/launchSettings.json | 31 ++++++++++++++++ .../ApiDotNetCore/WeatherForecast.cs | 13 +++++++ .../appsettings.Development.json | 8 +++++ ApiDotNetCore/ApiDotNetCore/appsettings.json | 9 +++++ 9 files changed, 157 insertions(+) create mode 100644 ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo create mode 100644 ApiDotNetCore/ApiDotNetCore.sln create mode 100644 ApiDotNetCore/ApiDotNetCore/ApiDotNetCore.csproj create mode 100644 ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs create mode 100644 ApiDotNetCore/ApiDotNetCore/Program.cs create mode 100644 ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json create mode 100644 ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs create mode 100644 ApiDotNetCore/ApiDotNetCore/appsettings.Development.json create mode 100644 ApiDotNetCore/ApiDotNetCore/appsettings.json diff --git a/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo b/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo new file mode 100644 index 0000000000000000000000000000000000000000..0085d6df4638c3859a2ca688a574b9111dd51f26 GIT binary patch literal 10752 zcmeHMPi$009R3wVK~%&dDk83>B8uD4ZD|WcWV_uJla@AYX)z%&`>&-?y3OuVAjrkU z#DktSCLWA>Aq2xw#e*C?=m9P!=t++n6VVG^pnl)HH@olczI{9UwwMq*n|b?Y-n{vK z^ZP&Zu3uaK%O{sN{VG*upRANSi)-Y5M}HgcSLpVmA`j!9eRmcY7umfM6}QXf9^$}l z&`S9&m;WaR4oM!rl7u8KbNDaFS(>tO*(j@AHgEEx_7^5&O~yDSXEJ`N$K1>KODX?V z4H$d##{AzmKfTfR2*<6p29H7G@^V~WhxSe3E-q&p%;J8$QC74y%l{pi0^v&)jZfTp znFR#}$)P4;3n|o`J+9tgX8`;Sn5@Xai83mufHEsHSU>Bu19=EN1#4K{EAiLiDdRHv zPkQM6~ufua&9$zudZ@>=1_9^i*C&sJ1Z zd}sU}!o1}4Nqgo=;Lk}Gy{ADzUU8*_KB8Ap0cMw-z$dOQy5H}A8y@bm2P84`tdg{a zVXboth|}mTC?9M+@t*Nz;BUku#uU=vJ<8p?8O;TIBQq*#M4u6$6>4}qQ6+2lELN){ z!1_1g)d_pD7*pyw z^1m7UM)|-t@c#+W!8mm{@Q1*a1?iSvF4m(^|A?!L$B>#X=lTyo>RHA6IryGgNF$*v zg3>5>TAX`2>K|h_V>4-RKlN@o@dqLK4E!(kKM#we?GM}fFr=(6Nqu&1hCKmA<>6g1L%O$qIf>v;;*6rc8@^B*sKE6bn<%BuXt zj~?iM)BLBes)x_~hdzk5$M{cdzoPvQW2));xtFOY{|f$DXntCGp$7O(uitI|Zv7v@ zdQSqC=P=G(te!0({xprxSUGMls#^Zu`tPK~&5d5@UkAF#dlvUo?-pfWPyQAXJ&?5% zkHQk>k)JXDoUwbIv(o=QiH>JcP4T(6)&4JmtUfL~5#Qs;yt+MM8-BS* z-Yk2`+T9WJZ{l_~fzNnB8(=ZRAIG>6(3b))+?o)?{vu|a1oLw@WO?E)teUoH z#i0Z=GNpD2HTX@(e`4$P`{7T(77CC#_lW884v}wU(R)mBV!zFQ%7BGDZB)4T()RC% zKdGY7oNqji1h7ADJ@omLAAZb^#d+}kHE@C+aUS`CQx5xpzXkI>hibZh?$=HD@5CPm zIx{k60!|%-{+Dgv6d&+qeBQTOh^tGha|L-{WAi`A`>npy3O-{|qssHY>M=b3tL|f) zxhVJJ+>_BSGcRF3^CSNAoP_#He;q=l-ZFmh{DMC8c~q}?bswf!E=$M(`T_cbprzIK z=?7cEryuA0l{x13qiI}Pr9VEB(5aL$rgLCqA~{CdBTT&gUY| zpusrA^91T!5bQYKvwcvTY^u*W--kch;3VK;TSkd;UL|bDl}LDu?i8gZL@i2gv@4?I z(R)cH-4rDgex|#XK7O9CL>cT^7q-+z%xZmhCB;6gK5Q@Sz)oz6oWF3n<$vdVhxaul zDV=L?M|Zsc?SacbU%1x(`Q*A`x&GB(N8auDGJbK-kC_i|ongv=l9Yj|4Oj16-7@^y z$Jt9CZ25C{y^+>$5SDSM2XKd(}DcIT^$+f}J7vjQy~* zF!~edi>bR9THHyp-G}c+VfF1OhV}ryd-UVKTYXbX$a$P!W^v~4#v72R|~(ZEG2Dw<<%vgu}k?a>%8wR_^COZa)iL8F*yuQOo21}=FZc + + + net6.0 + enable + enable + + + + + + + diff --git a/ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs b/ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..8005cbb --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace ApiDotNetCore.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} \ No newline at end of file diff --git a/ApiDotNetCore/ApiDotNetCore/Program.cs b/ApiDotNetCore/ApiDotNetCore/Program.cs new file mode 100644 index 0000000..48863a6 --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Program.cs @@ -0,0 +1,25 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json b/ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json new file mode 100644 index 0000000..db995b0 --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:64140", + "sslPort": 44396 + } + }, + "profiles": { + "ApiDotNetCore": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7293;http://localhost:5293", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs b/ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs new file mode 100644 index 0000000..de94d53 --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace ApiDotNetCore +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} \ No newline at end of file diff --git a/ApiDotNetCore/ApiDotNetCore/appsettings.Development.json b/ApiDotNetCore/ApiDotNetCore/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/ApiDotNetCore/ApiDotNetCore/appsettings.json b/ApiDotNetCore/ApiDotNetCore/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} From d1fe92eefb387e5b5ee58614065956bb068e6bef Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 05:48:39 -0300 Subject: [PATCH 13/35] update: alter path file gitignore --- ApiDotNetFramework/.gitignore => .gitignore | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ApiDotNetFramework/.gitignore => .gitignore (100%) diff --git a/ApiDotNetFramework/.gitignore b/.gitignore similarity index 100% rename from ApiDotNetFramework/.gitignore rename to .gitignore From 6850651d2c6a4024ef2b55b2c4e5afb733f64fb1 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:27:59 -0300 Subject: [PATCH 14/35] feat: remove controller default .net --- ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs diff --git a/ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs b/ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs deleted file mode 100644 index de94d53..0000000 --- a/ApiDotNetCore/ApiDotNetCore/WeatherForecast.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace ApiDotNetCore -{ - public class WeatherForecast - { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - - public string? Summary { get; set; } - } -} \ No newline at end of file From 60405ed835e5c2983b2bba291c143086954543fd Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:28:21 -0300 Subject: [PATCH 15/35] feat: create configuration class --- ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs diff --git a/ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs b/ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs new file mode 100644 index 0000000..392ee4a --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs @@ -0,0 +1,7 @@ +namespace ApiDotNetCore.Config +{ + public static class Configuration + { + public static string ConnectionString { get; set; } = "Data Source=localhost,1433;Initial Catalog=DB_DESAFIO_DOTNET;Integrated Security=False;User Id=sa;Password=1q2w3e4r@;MultipleActiveResultSets=True"; + } +} From be8f74b642b3f388185d4443261836debe116bb0 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:28:38 -0300 Subject: [PATCH 16/35] feat: create result view model --- .../ViewModel/ResultViewModel.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCore/ViewModel/ResultViewModel.cs diff --git a/ApiDotNetCore/ApiDotNetCore/ViewModel/ResultViewModel.cs b/ApiDotNetCore/ApiDotNetCore/ViewModel/ResultViewModel.cs new file mode 100644 index 0000000..3d8387c --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/ViewModel/ResultViewModel.cs @@ -0,0 +1,33 @@ +namespace ApiDotNetCore.ViewModel +{ + public class ResultViewModel + { + public ResultViewModel(T data, List errors) + { + Data = data; + Errors = errors; + } + + public ResultViewModel(T data) + { + Data = data; + + } + + public ResultViewModel(List errors) + { + Errors = errors; + } + + public ResultViewModel(string error) + { + Errors.Add(error); + } + + + + public T Data { get; private set; } + + public List Errors { get; private set; } = new List(); + } +} From 16d5920233b44ea4daa0cfa6ff0b8aeb10b65fe7 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:28:52 -0300 Subject: [PATCH 17/35] feat: create sql server repository --- .../Repositories/SqlServerRepository.cs | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCore/Repositories/SqlServerRepository.cs diff --git a/ApiDotNetCore/ApiDotNetCore/Repositories/SqlServerRepository.cs b/ApiDotNetCore/ApiDotNetCore/Repositories/SqlServerRepository.cs new file mode 100644 index 0000000..13fb16d --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Repositories/SqlServerRepository.cs @@ -0,0 +1,165 @@ +using ApiDotNetCore.Config; +using ApiDotNetCore.Entities; +using ApiDotNetCore.Interfaces; +using System.Data; +using System.Data.SqlClient; + +namespace ApiDotNetCore.Repositories +{ + public class SqlServerRepository : IRepository + { + protected string stringConnection; + public SqlServerRepository() + { + stringConnection = Configuration.ConnectionString; + } + + public List GetAll() + { + using (var conn = new SqlConnection(stringConnection)) + { + List listaProdutos = new List(); + ProductEntity produto = null; + try + { + SqlCommand cmd = new SqlCommand("sp_select_products", conn); + cmd.CommandType = CommandType.StoredProcedure; + conn.Open(); + using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) + { + while (reader.Read()) + { + produto = new ProductEntity() + { + CreatedAt = (DateTime)reader["createdAt"], + Name = reader["name"].ToString(), + Price = (double)reader["price"], + Brand = reader["brand"].ToString(), + UpdatedAt = (DateTime?)reader["updatedAt"], + Id = (int)reader["id"], + }; + listaProdutos.Add(produto); + } + } + } + catch (Exception error) + { + throw error; + } + return listaProdutos; + } + } + + public ProductEntity GetById(int id) + { + using (var conn = new SqlConnection(stringConnection)) + { + ProductEntity produto = null; + try + { + SqlCommand cmd = new SqlCommand("sp_select_products", conn); + cmd.CommandType = CommandType.StoredProcedure; + conn.Open(); + cmd.Parameters.AddWithValue("@id", id); + using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) + { + while (reader.Read()) + { + produto = new ProductEntity() + { + CreatedAt = (DateTime)reader["createdAt"], + Name = reader["name"].ToString(), + Price = (double)reader["price"], + Brand = reader["brand"].ToString(), + UpdatedAt = (DateTime?)reader["updatedAt"], + Id = (int)reader["id"], + }; + } + } + } + catch (Exception error) + { + throw error; + } + return produto; + } + } + + public int Insert(ProductEntity entity) + { + using (var conn = new SqlConnection(stringConnection)) + { + try + { + var cmd = new SqlCommand("sp_insert_products", conn); + conn.Open(); + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.AddWithValue("@name", entity.Name); + cmd.Parameters.AddWithValue("@brand", entity.Brand); + cmd.Parameters.AddWithValue("@price", entity.Price); + + SqlParameter id = new SqlParameter(); + id.ParameterName = "@id"; + id.Direction = ParameterDirection.Output; + id.SqlDbType = SqlDbType.Int; + cmd.Parameters.Add(id); + + cmd.ExecuteNonQuery(); + + return (int)id.Value; + } + catch (Exception error) + { + + throw error; + } + + } + } + + public void Update(ProductEntity entity, int id) + { + using (var conn = new SqlConnection(stringConnection)) + { + try + { + var cmd = new SqlCommand("sp_update_products", conn); + conn.Open(); + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.AddWithValue("@id", id); + cmd.Parameters.AddWithValue("@name", entity.Name); + cmd.Parameters.AddWithValue("@brand", entity.Brand); + cmd.Parameters.AddWithValue("@price", entity.Price); + cmd.ExecuteNonQuery(); + + } + catch (Exception error) + { + throw error; + } + + } + } + + public void Delete(int id) + { + using (var conn = new SqlConnection(stringConnection)) + { + try + { + var cmd = new SqlCommand("sp_delete_products", conn); + conn.Open(); + cmd.CommandType = CommandType.StoredProcedure; + cmd.Parameters.AddWithValue("@id", id); + cmd.ExecuteNonQuery(); + } + catch (Exception error) + { + throw error; + } + + } + } + + } +} From df975c5fc2cc9ae6950ed2724b7106b9cfdd63c9 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:29:05 -0300 Subject: [PATCH 18/35] feat: create fake repository --- .../Repositories/FakeRepository.cs | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCore/Repositories/FakeRepository.cs diff --git a/ApiDotNetCore/ApiDotNetCore/Repositories/FakeRepository.cs b/ApiDotNetCore/ApiDotNetCore/Repositories/FakeRepository.cs new file mode 100644 index 0000000..28e5826 --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Repositories/FakeRepository.cs @@ -0,0 +1,71 @@ +using ApiDotNetCore.Entities; + +namespace ApiDotNetCore.Repositories +{ + public class FakeRepository + { + public List listaProdutos; + + public FakeRepository() + { + listaProdutos = new List(); + listaProdutos.Add(new ProductEntity() { Id = 1, Name = "Product01", Brand = "Brand01", Price = 2.0 }); + listaProdutos.Add(new ProductEntity() { Id = 2, Name = "Product02", Brand = "Brand02", Price = 2.5 }); + listaProdutos.Add(new ProductEntity() { Id = 3, Name = "Product03", Brand = "Brand03", Price = 1.2 }); + listaProdutos.Add(new ProductEntity() { Id = 4, Name = "Product04", Brand = "Brand04", Price = 7.7 }); + listaProdutos.Add(new ProductEntity() { Id = 5, Name = "Product05", Brand = "Brand05", Price = 4.3 }); + listaProdutos.Add(new ProductEntity() { Id = 6, Name = "Product06", Brand = "Brand06", Price = 5.1 }); + } + + public List GetAll() + { + return listaProdutos; + } + + public ProductEntity GetById(int id) + { + return listaProdutos.FirstOrDefault(x => x.Id == id); + } + + public int Insert(ProductEntity entity) + { + var maxId = listaProdutos.Max(t => t.Id); + maxId++; + + var produto = new ProductEntity() + { + Id = maxId, + Name = entity.Name, + Brand = entity.Brand, + Price = entity.Price, + CreatedAt = DateTime.Now + }; + listaProdutos.Add(produto); + return maxId; + } + + public void Update(ProductEntity entity, int id) + { + var index = listaProdutos.FindIndex(t => t.Id == id); + + if (index != null) + { + listaProdutos[index].Name = entity.Name; + listaProdutos[index].Brand = entity.Brand; + listaProdutos[index].Price = entity.Price; + listaProdutos[index].UpdatedAt = DateTime.Now; + } + } + + public void Delete(int id) + { + var index = listaProdutos.FindIndex(t => t.Id == id); + + if (index != null) + { + listaProdutos.RemoveAt(index); + + } + } + } +} From 068f008b09c5af94d5731b35df26828a1fb92f39 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:29:18 -0300 Subject: [PATCH 19/35] feat: create interface repository --- ApiDotNetCore/ApiDotNetCore/Interfaces/IRepository.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCore/Interfaces/IRepository.cs diff --git a/ApiDotNetCore/ApiDotNetCore/Interfaces/IRepository.cs b/ApiDotNetCore/ApiDotNetCore/Interfaces/IRepository.cs new file mode 100644 index 0000000..48ce534 --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Interfaces/IRepository.cs @@ -0,0 +1,11 @@ +namespace ApiDotNetCore.Interfaces +{ + public interface IRepository where TEntity : class + { + List GetAll(); + TEntity GetById(TKey id); + int Insert(TEntity entity); + void Update(TEntity entity, TKey id); + void Delete(TKey id); + } +} From b76e71d0a3fe6a7ae13153ae74bc6626c5d3b50f Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:29:36 -0300 Subject: [PATCH 20/35] feat: create product entity --- .../ApiDotNetCore/Entities/ProductEntity.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCore/Entities/ProductEntity.cs diff --git a/ApiDotNetCore/ApiDotNetCore/Entities/ProductEntity.cs b/ApiDotNetCore/ApiDotNetCore/Entities/ProductEntity.cs new file mode 100644 index 0000000..be2463e --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Entities/ProductEntity.cs @@ -0,0 +1,29 @@ +using System.ComponentModel.DataAnnotations; + +namespace ApiDotNetCore.Entities +{ + public class ProductEntity + { + public int Id { get; set; } + [Required(ErrorMessage = "the field name missing.")] + public string Name { get; set; } + public string Brand { get; set; } + [Required(ErrorMessage = "the filed price missing.")] + public double Price { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + + public ProductEntity() + { + + } + + public ProductEntity(string name, string brand, double price) + { + Name = name; + Brand = brand; + Price = price; + } + + } +} From 92306d14322e156af31bdf56b4dec108bcaa3328 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:29:56 -0300 Subject: [PATCH 21/35] feat: remove controller default .net --- .../Controllers/WeatherForecastController.cs | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs diff --git a/ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs b/ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs deleted file mode 100644 index 8005cbb..0000000 --- a/ApiDotNetCore/ApiDotNetCore/Controllers/WeatherForecastController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Mvc; - -namespace ApiDotNetCore.Controllers -{ - [ApiController] - [Route("[controller]")] - public class WeatherForecastController : ControllerBase - { - private static readonly string[] Summaries = new[] - { - "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" - }; - - private readonly ILogger _logger; - - public WeatherForecastController(ILogger logger) - { - _logger = logger; - } - - [HttpGet(Name = "GetWeatherForecast")] - public IEnumerable Get() - { - return Enumerable.Range(1, 5).Select(index => new WeatherForecast - { - Date = DateTime.Now.AddDays(index), - TemperatureC = Random.Shared.Next(-20, 55), - Summary = Summaries[Random.Shared.Next(Summaries.Length)] - }) - .ToArray(); - } - } -} \ No newline at end of file From e7dd3622dbb7b475543c0c6932747a4e09298bd2 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:30:13 -0300 Subject: [PATCH 22/35] feat: create product controller --- .../Controllers/ProductController.cs | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCore/Controllers/ProductController.cs diff --git a/ApiDotNetCore/ApiDotNetCore/Controllers/ProductController.cs b/ApiDotNetCore/ApiDotNetCore/Controllers/ProductController.cs new file mode 100644 index 0000000..237c164 --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCore/Controllers/ProductController.cs @@ -0,0 +1,129 @@ +using ApiDotNetCore.Entities; +using ApiDotNetCore.Repositories; +using ApiDotNetCore.ViewModel; +using Microsoft.AspNetCore.Mvc; + +namespace ApiDotNetCore.Controllers +{ + [ApiController] + [Route("[controller]")] + public class ProductController : ControllerBase + { + private SqlServerRepository respository = new SqlServerRepository(); + + + [HttpGet("/api/v1/products")] + public async Task GetAsync() + { + try + { + var data = respository.GetAll(); + return Ok(new ResultViewModel(data)); + } + catch + { + return StatusCode(500, new ResultViewModel("Internal server error")); + } + } + + [HttpGet("/api/v1/products/{productId}")] + public async Task GetByIdAsync( + [FromRoute] int productId) + { + + try + { + var data = respository.GetById(productId); + if (data == null) + return NotFound(new ResultViewModel("Not Content Found")); + + return Ok(new ResultViewModel(data)); + } + catch + { + return StatusCode(500, new ResultViewModel("Internal server error")); + } + } + + [HttpPost("/api/v1/products")] + public async Task PostAsync( + [FromBody] ProductEntity product) + { + + if (!ModelState.IsValid) + return BadRequest(new ResultViewModel(ModelState)); + + try + { + var id = respository.Insert(product); + product.Id = id; + product.CreatedAt = DateTime.Now; + + return Ok(new ResultViewModel(product)); + } + catch (Exception error) + { + return StatusCode(500, new ResultViewModel("Error to create product.")); + } + catch + { + return StatusCode(500, new ResultViewModel("Internal server erro")); + } + } + + [HttpPut("/api/v1/products/{productId}")] + public async Task PutAsync( + [FromRoute] int productId, + [FromBody] ProductEntity product) + { + + try + { + var data = respository.GetById(productId); + if (data == null) return NotFound(new ResultViewModel("Not Content Found.")); + + data.Name = product.Name; + data.Brand = product.Brand; + data.Price = product.Price; + data.UpdatedAt = DateTime.Now; + respository.Update(data, productId); + return Ok(new ResultViewModel(data)); + } + catch (Exception error) + { + return StatusCode(500, new ResultViewModel("Error to update product.")); + } + catch + { + return StatusCode(500, new ResultViewModel("Internal server error")); + } + + + } + + [HttpDelete("/api/v1/products/{productId}")] + public async Task DeleteAsync( + [FromRoute] int productId) + { + + try + { + var data = respository.GetById(productId); + if (data == null) return NotFound(new ResultViewModel("Not Content Found.")); + respository.Delete(productId); + return Ok(new ResultViewModel(data)); + } + catch (Exception error) + { + return StatusCode(500, new ResultViewModel("Error to update product.")); + } + catch + { + return StatusCode(500, new ResultViewModel("Internal server error")); + } + + + + } + } +} \ No newline at end of file From 5bf4b78d0120ebb1e5baf2bac69297348275c1a0 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:30:49 -0300 Subject: [PATCH 23/35] feat: configuration files --- ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo | Bin 10752 -> 44032 bytes .../ApiDotNetCore/ApiDotNetCore.csproj | 3 +++ ApiDotNetCore/ApiDotNetCore/Program.cs | 10 ---------- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo b/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo index 0085d6df4638c3859a2ca688a574b9111dd51f26..660bca29fdf10a81f8212196e7f2437ae02bc2f2 100644 GIT binary patch literal 44032 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 J5B$2c{|AiywR!*m delta 1337 zcmZuxO-~b16rDGnw$l$v5s*@_UlgoBu-1?u(O9G=SO^7MKoetFj4L6jk*eULLt@;S zK#vRKio_p4h>0r`n;6%!#D77IlgL8w-k}4dVUpAL-nsAHckg-kR^OBL(ncD)X-`{F zlA0t*5`@E}qazw52WFkyJBx~N{vqaYXLeg`E>6|tDWq0Ak(QgqA)=#kY-urC1rS?3 zp7VN3i=MeIPj-<5;Y3`H2KM*LKleZEi2&c`!>7Q#6~E5XdO z=5s-g+)`N%Caqh=B~&5>)j<@WIiXW9h;Ae5f}OsIN_5&IV#M{>c&Di_4mu|}UsoTQ zh9#_p^Xhq;vKp4-+G7R3!!wvj4vH`;T`bED=$RN|nWSo^WbMYvgBi7hj&r^zINWKm%uEeb2WC2U>eH~0H_FFWP07997O za(C0>bazk}K^WPB%1_i~Gl>8yV@0LYM)~=Eelh-P{S%mQ3?ds>@S+sLM*oNsCf;%_ zd@vpskjq?$J}{229mDRDd5}^m-myXyDk`Od8X`;7e%KA8R242%=BiYV#$2P~hUl*O zDYFh8Fy^bsE-MuO>O$TlMd*Co<^%P#BK$b$cu86)W}I)eL6j%E&#e99zBug->IJlU zNk^|DylC;Zie~!l7;C31xDfayIcye)--)&3kxPt2;dEjI4kOXtUv%Ki#XMPIg{X zIY1v$@lH$8JP5t~44;+~4V#MWP}ZFD-fW^BZ?u8HZ3>qgkortWVZ@4IM`M(KNO)5H zOjS=L+_iZw+mjD^Z2|AKKKe)a_+|aMY%@|P$*%{fhD@K*W;}$L8IjL%@4L5=bO7~N WDfG!9Tc#9YF8GfUR+j&bLi!8JV_@X~ diff --git a/ApiDotNetCore/ApiDotNetCore/ApiDotNetCore.csproj b/ApiDotNetCore/ApiDotNetCore/ApiDotNetCore.csproj index 60bf9ea..c8f7956 100644 --- a/ApiDotNetCore/ApiDotNetCore/ApiDotNetCore.csproj +++ b/ApiDotNetCore/ApiDotNetCore/ApiDotNetCore.csproj @@ -8,6 +8,9 @@ + + + diff --git a/ApiDotNetCore/ApiDotNetCore/Program.cs b/ApiDotNetCore/ApiDotNetCore/Program.cs index 48863a6..6845b99 100644 --- a/ApiDotNetCore/ApiDotNetCore/Program.cs +++ b/ApiDotNetCore/ApiDotNetCore/Program.cs @@ -1,25 +1,15 @@ var builder = WebApplication.CreateBuilder(args); - -// Add services to the container. - builder.Services.AddControllers(); -// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); - -// Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } -app.UseHttpsRedirection(); - app.UseAuthorization(); - app.MapControllers(); - app.Run(); From afa4a7100e2821c9719a9b33dc1131b34704d132 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:35:22 -0300 Subject: [PATCH 24/35] feat: create test project --- ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo | Bin 44032 -> 46592 bytes ApiDotNetCore/ApiDotNetCore.sln | 6 +++++ .../ApiDotNetCoreTest.csproj | 22 ++++++++++++++++++ ApiDotNetCore/ApiDotNetCoreTest/Usings.cs | 1 + 4 files changed, 29 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCoreTest/ApiDotNetCoreTest.csproj create mode 100644 ApiDotNetCore/ApiDotNetCoreTest/Usings.cs diff --git a/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo b/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo index 660bca29fdf10a81f8212196e7f2437ae02bc2f2..4ed2c918b435c7a67f6089411e18df5849388c43 100644 GIT binary patch literal 46592 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 XH*&+x_*z-?-E_#-2N9Qg8TbANgxDvn diff --git a/ApiDotNetCore/ApiDotNetCore.sln b/ApiDotNetCore/ApiDotNetCore.sln index 29cd1c7..1b257bc 100644 --- a/ApiDotNetCore/ApiDotNetCore.sln +++ b/ApiDotNetCore/ApiDotNetCore.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.2.32630.192 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDotNetCore", "ApiDotNetCore\ApiDotNetCore.csproj", "{BB23EC7D-4FBC-4C41-BC69-9ACB857B13AF}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDotNetCoreTest", "ApiDotNetCoreTest\ApiDotNetCoreTest.csproj", "{4C55C1FC-325E-48BA-9165-895F1AD71A00}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {BB23EC7D-4FBC-4C41-BC69-9ACB857B13AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {BB23EC7D-4FBC-4C41-BC69-9ACB857B13AF}.Release|Any CPU.ActiveCfg = Release|Any CPU {BB23EC7D-4FBC-4C41-BC69-9ACB857B13AF}.Release|Any CPU.Build.0 = Release|Any CPU + {4C55C1FC-325E-48BA-9165-895F1AD71A00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C55C1FC-325E-48BA-9165-895F1AD71A00}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C55C1FC-325E-48BA-9165-895F1AD71A00}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C55C1FC-325E-48BA-9165-895F1AD71A00}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ApiDotNetCore/ApiDotNetCoreTest/ApiDotNetCoreTest.csproj b/ApiDotNetCore/ApiDotNetCoreTest/ApiDotNetCoreTest.csproj new file mode 100644 index 0000000..5af790a --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCoreTest/ApiDotNetCoreTest.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + + + + diff --git a/ApiDotNetCore/ApiDotNetCoreTest/Usings.cs b/ApiDotNetCore/ApiDotNetCoreTest/Usings.cs new file mode 100644 index 0000000..ab67c7e --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCoreTest/Usings.cs @@ -0,0 +1 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file From c9945b7c1d8f93e5930e17ec1644da18001c8cf4 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sat, 30 Jul 2022 06:35:35 -0300 Subject: [PATCH 25/35] test: create product test --- .../ApiDotNetCoreTest/ProductTest.cs | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 ApiDotNetCore/ApiDotNetCoreTest/ProductTest.cs diff --git a/ApiDotNetCore/ApiDotNetCoreTest/ProductTest.cs b/ApiDotNetCore/ApiDotNetCoreTest/ProductTest.cs new file mode 100644 index 0000000..2f1f41e --- /dev/null +++ b/ApiDotNetCore/ApiDotNetCoreTest/ProductTest.cs @@ -0,0 +1,79 @@ +using ApiDotNetCore.Entities; +using ApiDotNetCore.Repositories; + +namespace ApiDotNetCoreTest +{ + [TestClass] + public class ProductTest + { + [TestMethod] + [TestCategory("Product")] + public void Should_Create_Valid_Product() + { + var product = new ProductEntity("Test", "Test", 7.5); + Assert.AreEqual(product.Name, "Test"); + Assert.AreEqual(product.Brand, "Test"); + Assert.AreEqual(product.Price, 7.5); + } + + + [TestMethod] + [TestCategory("Product")] + public void Should_Get_All_Products() + { + var repository = new FakeRepository(); + var listaProdutos = repository.GetAll(); + Assert.AreEqual(listaProdutos.Count, 6); + } + + [TestMethod] + [TestCategory("Product")] + public void Should_Get_Product_ById() + { + var repository = new FakeRepository(); + var produto = repository.GetById(2); + Assert.AreEqual(produto.Id, 2); + Assert.AreEqual(produto.Name, "Product02"); + Assert.AreEqual(produto.Brand, "Brand02"); + Assert.AreEqual(produto.Price, 2.5); + } + + + [TestMethod] + [TestCategory("Product")] + public void Should_Insert_New_Product() + { + var repository = new FakeRepository(); + var totalProducts = repository.listaProdutos.Count; + var Id = totalProducts + 1; + var product = new ProductEntity() { Name = "Product" + Id, Brand = "Brand" + Id, Price = 4.99 }; + repository.Insert(product); + Assert.IsTrue(repository.listaProdutos.Count > totalProducts); + } + + [TestMethod] + [TestCategory("Product")] + public void Should_Update_Product() + { + var repository = new FakeRepository(); + var totalProducts = repository.listaProdutos.Count; + var Id = 3; + var product = new ProductEntity() { Name = "ProductUpdated", Brand = "BrandUpdated", Price = 9.99 }; + repository.Update(product, Id); + var Index = repository.listaProdutos.FindIndex(x => x.Id == Id); + Assert.IsTrue(repository.listaProdutos[Index].Name == "ProductUpdated"); + Assert.IsTrue(repository.listaProdutos[Index].Brand == "BrandUpdated"); + Assert.IsTrue(repository.listaProdutos[Index].Price == 9.99); + } + + [TestMethod] + [TestCategory("Product")] + public void Should_Delete_Product() + { + var repository = new FakeRepository(); + var totalProducts = repository.listaProdutos.Count; + repository.Delete(2); + Assert.IsTrue(repository.listaProdutos.Count < totalProducts); + } + } +} \ No newline at end of file From 67de28e0c5070e50a2253bb23367ffe3e6498fb5 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:24:32 -0300 Subject: [PATCH 26/35] feat: move path docker-compose --- docker-compose.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f6e7fe7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +version: '3' +services: + sqlserver: + image: mcr.microsoft.com/mssql/server + container_name: SQLSERVER + environment: + - ACCEPT_EULA=Y + - SA_PASSWORD=1q2w3e4r@ + ports: + - "1433:1433" + volumes: + - .\Database:/var/opt/mssql/data From faf35010d211486c57f525d52a6113e252ea8a44 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:26:24 -0300 Subject: [PATCH 27/35] feat: create config. json ocelot --- .../Properties/launchSettings.json | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 ApiDotNetGateway/ApiDotNetGateway/Properties/launchSettings.json diff --git a/ApiDotNetGateway/ApiDotNetGateway/Properties/launchSettings.json b/ApiDotNetGateway/ApiDotNetGateway/Properties/launchSettings.json new file mode 100644 index 0000000..21be2fc --- /dev/null +++ b/ApiDotNetGateway/ApiDotNetGateway/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:23142", + "sslPort": 44333 + } + }, + "profiles": { + "ApiDotNetGateway": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7003;http://localhost:5003", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} From 56bf23b6f12ed4208e5707b9d1dca3e55a96f8b7 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:26:40 -0300 Subject: [PATCH 28/35] feat: create file ocelot.json --- ApiDotNetGateway/ApiDotNetGateway/ocelot.json | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 ApiDotNetGateway/ApiDotNetGateway/ocelot.json diff --git a/ApiDotNetGateway/ApiDotNetGateway/ocelot.json b/ApiDotNetGateway/ApiDotNetGateway/ocelot.json new file mode 100644 index 0000000..b72b65f --- /dev/null +++ b/ApiDotNetGateway/ApiDotNetGateway/ocelot.json @@ -0,0 +1,41 @@ +{ + "GlobalConfiguration": { + "GlobalConfiguration": { + "BaseUrl": "http://localhost:5003" + } + }, + "ReRoutes": [ + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 5001 + } + ], + "UpstreamPathTemplate": "/api/{version}/c/{everything}", + "UpstreamHttpMethod": [ "POST", "PUT", "GET" ], + "AuthenticationOptions": { + "AuthenticationProviderKey": "IdentityApiKey", + "AllowedScopes": [] + } + }, + { + "DownstreamPathTemplate": "/api/{version}/{everything}", + "DownstreamScheme": "http", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 5002 + } + ], + "UpstreamPathTemplate": "/api/{version}/c/{everything}", + "UpstreamHttpMethod": [ "POST", "PUT", "GET" ], + "AuthenticationOptions": { + "AuthenticationProviderKey": "IdentityApiKey", + "AllowedScopes": [] + } + } + ] +} \ No newline at end of file From 82b71a63f53254de5b6691b5d6d4afd5ac218909 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:27:12 -0300 Subject: [PATCH 29/35] feat: configuration ocelot --- ApiDotNetGateway/ApiDotNetGateway.sln | 25 +++++++++++++++++++ .../ApiDotNetGateway/ApiDotNetGateway.csproj | 13 ++++++++++ .../appsettings.Development.json | 8 ++++++ .../ApiDotNetGateway/appsettings.json | 9 +++++++ 4 files changed, 55 insertions(+) create mode 100644 ApiDotNetGateway/ApiDotNetGateway.sln create mode 100644 ApiDotNetGateway/ApiDotNetGateway/ApiDotNetGateway.csproj create mode 100644 ApiDotNetGateway/ApiDotNetGateway/appsettings.Development.json create mode 100644 ApiDotNetGateway/ApiDotNetGateway/appsettings.json diff --git a/ApiDotNetGateway/ApiDotNetGateway.sln b/ApiDotNetGateway/ApiDotNetGateway.sln new file mode 100644 index 0000000..d519ead --- /dev/null +++ b/ApiDotNetGateway/ApiDotNetGateway.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32630.192 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDotNetGateway", "ApiDotNetGateway\ApiDotNetGateway.csproj", "{599F7D03-B4E5-4570-95F9-A08225EEC39A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {599F7D03-B4E5-4570-95F9-A08225EEC39A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {599F7D03-B4E5-4570-95F9-A08225EEC39A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {599F7D03-B4E5-4570-95F9-A08225EEC39A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {599F7D03-B4E5-4570-95F9-A08225EEC39A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {83BCA4D9-86A9-45FB-B9D7-B011DAA665E4} + EndGlobalSection +EndGlobal diff --git a/ApiDotNetGateway/ApiDotNetGateway/ApiDotNetGateway.csproj b/ApiDotNetGateway/ApiDotNetGateway/ApiDotNetGateway.csproj new file mode 100644 index 0000000..3af46f9 --- /dev/null +++ b/ApiDotNetGateway/ApiDotNetGateway/ApiDotNetGateway.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/ApiDotNetGateway/ApiDotNetGateway/appsettings.Development.json b/ApiDotNetGateway/ApiDotNetGateway/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/ApiDotNetGateway/ApiDotNetGateway/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/ApiDotNetGateway/ApiDotNetGateway/appsettings.json b/ApiDotNetGateway/ApiDotNetGateway/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/ApiDotNetGateway/ApiDotNetGateway/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} From 7f4ab9e3f14e6bc96e2fb768e1c3d739dd677456 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:27:27 -0300 Subject: [PATCH 30/35] feat: remove file this path --- ApiDotNetFramework/docker-compose.yml | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 ApiDotNetFramework/docker-compose.yml diff --git a/ApiDotNetFramework/docker-compose.yml b/ApiDotNetFramework/docker-compose.yml deleted file mode 100644 index f6e7fe7..0000000 --- a/ApiDotNetFramework/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: '3' -services: - sqlserver: - image: mcr.microsoft.com/mssql/server - container_name: SQLSERVER - environment: - - ACCEPT_EULA=Y - - SA_PASSWORD=1q2w3e4r@ - ports: - - "1433:1433" - volumes: - - .\Database:/var/opt/mssql/data From 8298bf1df42afb392194508d599998c7740b4d9f Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:27:47 -0300 Subject: [PATCH 31/35] update: update webconfig --- ApiDotNetFramework/ApiDotNetFramework/Web.config | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ApiDotNetFramework/ApiDotNetFramework/Web.config b/ApiDotNetFramework/ApiDotNetFramework/Web.config index 79f4c07..cd3f1d7 100644 --- a/ApiDotNetFramework/ApiDotNetFramework/Web.config +++ b/ApiDotNetFramework/ApiDotNetFramework/Web.config @@ -5,14 +5,9 @@ --> - + connectionString="Data Source=localhost,1433;Initial Catalog=DB_DESAFIO_DOTNET_FRAMEWORK;Integrated Security=False;User Id=sa;Password=1q2w3e4r@;MultipleActiveResultSets=True" /> From 9a9b4c4547d072c02f0feae7c778ecaecf2cbfee Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:28:14 -0300 Subject: [PATCH 32/35] feat: alter port to 5002 --- ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj b/ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj index 4721915..207b28e 100644 --- a/ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj +++ b/ApiDotNetFramework/ApiDotNetFramework/ApiDotNetFramework.csproj @@ -153,7 +153,7 @@ True 53455 / - http://localhost:53455/ + http://localhost:5002/ False False From faa21cbefc31440aeef344d112320978a3cfda3a Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:28:35 -0300 Subject: [PATCH 33/35] feat: alter port to 5001 --- ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json | 2 +- ApiDotNetFramework/ApiDotNetFramework.sln | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json b/ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json index db995b0..61d0edc 100644 --- a/ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json +++ b/ApiDotNetCore/ApiDotNetCore/Properties/launchSettings.json @@ -14,7 +14,7 @@ "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "https://localhost:7293;http://localhost:5293", + "applicationUrl": "https://localhost:7001;http://localhost:5001", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/ApiDotNetFramework/ApiDotNetFramework.sln b/ApiDotNetFramework/ApiDotNetFramework.sln index 41f2f3a..91d91e9 100644 --- a/ApiDotNetFramework/ApiDotNetFramework.sln +++ b/ApiDotNetFramework/ApiDotNetFramework.sln @@ -7,8 +7,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDotNetFramework", "ApiDo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiDotNetFramework.Tests", "ApiDotNetFramework.Tests\ApiDotNetFramework.Tests.csproj", "{939D1ED1-8075-45EC-BA70-067AA23339DD}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Database", "Database", "{61FA303C-C290-4F9C-88C5-FE8A5CC169D7}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU From 129e5f4e682667a4a0397162e4220e890a9c10e5 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:28:54 -0300 Subject: [PATCH 34/35] feat: alter connection string to sql server --- ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs b/ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs index 392ee4a..553318c 100644 --- a/ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs +++ b/ApiDotNetCore/ApiDotNetCore/Config/Configuration.cs @@ -2,6 +2,6 @@ { public static class Configuration { - public static string ConnectionString { get; set; } = "Data Source=localhost,1433;Initial Catalog=DB_DESAFIO_DOTNET;Integrated Security=False;User Id=sa;Password=1q2w3e4r@;MultipleActiveResultSets=True"; + public static string ConnectionString { get; set; } = "Data Source=localhost,1433;Initial Catalog=DB_DESAFIO_DOTNET_CORE;Integrated Security=False;User Id=sa;Password=1q2w3e4r@;MultipleActiveResultSets=True"; } } From 546de9598f3c805e8730ae3c94f5eff0a0f72e78 Mon Sep 17 00:00:00 2001 From: Cleyton Date: Sun, 31 Jul 2022 12:29:06 -0300 Subject: [PATCH 35/35] =?UTF-8?q?feat:=20altera=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo | Bin 46592 -> 61952 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo b/ApiDotNetCore/.vs/ApiDotNetCore/v17/.suo index 4ed2c918b435c7a67f6089411e18df5849388c43..0dfe1c6e3d1df0caf46e395fce4b026f801ebaa9 100644 GIT binary patch literal 61952 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
&o_NdB@e7n^ z?tlBV3#R*NJDUlY3H%E^DPH;c(Hn<; z| zi}T74;Fn-|Ujsd}6VQO`Mw|y&jrfgt%5Q?U;DFL9ERLL&hF91tNvziS7hm^e+)>K3 zBIk_*I9q8E!M3b!SEkP;&9eNzt0YHrid~lf(PPb7gQY}33cDxE{~W7j`HwTfLRQf@ z6VyeUvivtF|DA`y!SO-Z^W?ur9D_el+tDD5O!^OR>P$?w+l1XO&F zPyeR7_@q0&WEc@wL4LR1a0lMhm;Mnyx&KO>KE7^ky{n<7(c4h#^t&6pPM^zF?`-hY z)j69zEiI=#&0H(W`X4!(X1egVwz1LUZT8nTIejgSey7jxb2}UTHTBN=27hB+b#0^D z+t9LpT|-}_DVA8IPDKxk;cq2o^8u(}R$^RLV0D0fieI|tFCBK5%`{{ig%H_>xtMYr zYRc?<$86eXp2JUDsHt_HT6dtnKH%(9>wQk2hdFlFhMm>kfG^|=S9^ltn&B{a&8w6d z4r#|Z=qSO8b-|e|iQyv*xwW6D2zj*Dy0r~8{#u`}q0Z@Q_BEgh{58(Hx|#;3tH$T4 z^SY{iHMPF=Hx#`TaeW70zl!a58QUtyEWTLuEEc7rQ@?hZ%Rs5CZ?3OtX>jE`P%OGo z_R23pwtrdl2Fd48xl|Gm6dywsp5bGtHiy9-C{mgK@7?@A50;hxNG!0wJ|~Bu&tF~b zcenVRUQczi(^uEn0A5v7?X0V>ZgDp>)w&y8t|W`q^2=S=sb|G9L^7d*ha#C4`B-Qm znBXoKi^ z&Er^*4|$LRzMz)L)DAU!u#3=C22@XNpr*^^RK31xr?=Wd0} z|1c}6bJo{{Fws*3VQ;-pRlPO!Rrm}}t+#HSPU8o?LlsBbA|UNQ=$gtCmb96D{$dh1 zLlGt{6QhBF-r#a+m8vN-9A^}Tl%?h_1w-W!@@5ga#Iln{8cm0W8@dFWLxZ*tO{F|_ zr1B>R{m%s~G&+-*SBIFL|GX6uznG1k@Ps(3P zDJwBMo78w99EoXmUTKTZsjFE0I-rG`G$);^-J$VGQey5UnvDZMpu>^wqzcDzdQk*K zq}iFC^f5!k$V{`&KJHZ{r3fW~^tT7VK^e~?BR)pQ7>8b?RL zJ)S9%;2Kh`Na^euBJ3u#Mef~P=Q#?%8ITlzilv`Q&Je`TT)8tvhD-UHqSnWb`%noI}amFRSd?-U`6&^%wh;tKuU0_|NaTL2o zYcw6*lNJTataAv57sN#z^Jld;nEOjo&%2fSXMR7t(Dj4T&=uvcKi_rv_d_4ot5Lvi zP(}~qroh4nHOBAA}`?TYxcyb06uZ38!7HbA$?-Ueqnn9sbcX9Y? zrhd%!%--88u#=g4w%--S;Q^;|KZo}H$JHhul{y8Vg2ZRJI%2VCys9J8ho6B+Un@R& z80c1u_Ho8JCfGSK&y2dNeIUl~8S=AMEXYx_8CM#n@=5wP$}~IXF=HXwMj$)M(a$ea zZ!HOKC)zOmFp((oIsh4uyX)H_L8Y$TCf5yxRdzyIq{U%BF_ZHLHv*ViyOvdF+%mkg z?5}pB{Y_bQmfYr2Xz$LXIs>iP^IfsHr_@fRa~~NlDQsE)mjHh;r^oV{thb%5|0`4y zc@ab4s_j#|)PTF%tA?FjUT>|_7wS@-b)GKV2I{)%ymbLrb=dR8^R`b7b%mh9qJ>@7`PVf167}BFxlVDDBTfucDP+rsuLZk$r6{p;B

xow4SX)KZqUn3>M=+xabEPEE^N%$;5PGX1g@>#ke1+BH_JWi2MT zzmP?(Wlkv(P)kNFrgk{%UabGi_uRZ<&70*)Za!-kNiA;vT1?Jy*l&`wF;#mk!)3oo zpT9ro$p7rYonMF9W#b(+7fgEN^lR5#RrS%jBU>i_@8<3UoB#Ih3tvC@yko~b^Jv#g gtRMOPFXg-Qd zXaelO$G{(f13)uy5I6)J2L1#b0geL4fKPzq03~@081!dUP6A&5Oiw$?Q+@R_C_8{o zZc~GLWWx+!Z8sX%fa|Pmm>6j_nKUV=J7{CCQL&Lk(IV4PmEgOhZBOYbPN5<5*c^5v z%_J!KQdq1%(ou&$^ie^>Ic)4NzwBM zFIc0;XvGkypKu;)j+W`5uINeXp|^F!^zt+iO1;1z#5!;cbEi6u`WYJ4kwvEXM#}9l zp-i>@fUV3oX;QHU+xN{~n@6;01;+}9tH@_Dm*!{%k4bbIt76aml5Pw=rs0Sc@6<(I z!&)^w-VyqGR|yOuulyvr!w~~}JMwci{+P~zj%W4qm)}awia3u9DA`OP)RUg+pwsm^ zDAL@i+W0d~5~>^v9dpGj>NaL;gEA?@FIt?Y%E39jXVqD#KX+V>HL00Q+BoVeUM1iQ$yu6V z=r#b3RfCvt-V_Vl4BvFGK~Z*Q0_p9pB9@k4@yGw^%E;hYMC4M*jCfrkEs_>UB~p|e z_u<%7^x5k0Vree41(FG)ils_vHtGxH87We%6i035P_I~NrZgYFUh$RipdhwM>D%Io z>4)4t^RCa6>^VCX+xtey`{BJIu~J)YsCO(DtO9z4AN}$1NU~ndrO{1sR{g8AqCJG{ z6YbUnlTwdCj*An%RGF|$cvAP2WkOJ8;xa@8rSPH~Q;#uu)D<>K{WvB#*dg=uTxt%B zQ?c>=m2M2r`oGN9LpED11tD>w z99+>8RUUSr`WJrVuQaA4AAZyApZova)$wAo_2)X8QKKXKQ%15cIYjoT!Sqh8H`rfU z6HT#|C#;@hw6F~M)xwE)Pm7pF-JUrbJ}|#|+`5v-ay6V>IpI2#Vk&h9=c)TUt9DUk zNH#l+c#XP4ay0x36W~1HRjLflA(JW9s>@LG%{W#gv#u{D>TvtII5PY9hC=qyPXQLP zj1Cit)TS_at@!$*sn>@b`t8xWi{9plZ)elrFRY<=F8I)y$_UEMQ>!^IG1)XNV_?7M zJXddcOQ%Om6=e_$*r1&~Y~;N>4D)XaJLz4Vg?c8BedrL^LSwY?Dmlba{2D*Y~_z|Nm@6!jR)80L_7j<+=)VVf*jEj9q zvu=p?T|OqyVxhLJ{*<;pl1#gjED~5WXuh|KMvmf8p;Im<=G}gga~V-lIBP1 z^*o4uoXgoL=KynodB8IOy%iZ9#hq1XECQ;5#lZ8x5@0E?46p#Vu4|`pg1Ga_G*Lm1 z_AYEaR`zRYwdd;NPY!U5$K&O@FC|* zE7pf;!L{@(a$Pw(esxFCv>BI-6Sqe`TWsYep)U+?dRlk9_Vkk*c6I0rFB<~;D{d4m zY)%g`oxgVS@Vs>#JaaQEoUF)$L{*lPn+oNUOOYRvvM!awn-q7KAM0uP`fwHRxr~f; zzO=MnNAv1+p5^Fb7lgz1t?7a7v?2+^TDf5Jd|l8p8FE{Lu)aZ9jfq%`yG4PjS?Pmo&ok-gp`9?3F0 z5HCh@=B4BH{$yz=6zO!eej?d7jS!>cTHK~I`q!p%nzzZFT(_*Dvd#5Ww7_SD(dAR$*q+=5pPRnVQ#h;N+i5%}sO9C6*p575Gqzq+lTUj!{iChC&*LL( Kg{>!L<^KR