├── .gitattributes
├── .gitignore
├── ASP.NETCore5.0WebAPI.pdf
├── CompanyEmployee.API
├── CompanyEmployee.API.csproj
├── CompanyEmployee.API.xml
├── Controllers
│ ├── AuthenticationController.cs
│ ├── CompaniesController.cs
│ ├── CompaniesV2Controller.cs
│ ├── EmployeesController.cs
│ └── WeatherForecastController.cs
├── Infrastructure
│ ├── ActionFilters
│ │ ├── ValidateCompanyExistsAttribute.cs
│ │ ├── ValidateEmployeeForCompanyExistsAttribute.cs
│ │ └── ValidationFilterAttribute.cs
│ ├── CsvOutputFormatter.cs
│ ├── Extensions
│ │ ├── ExceptionMiddlewareExtensions.cs
│ │ └── ServiceExtensions.cs
│ ├── MappingProfile.cs
│ └── ModelBinders
│ │ └── ArrayModelBinder.cs
├── Migrations
│ ├── 20210109115024_Init.Designer.cs
│ ├── 20210109115024_Init.cs
│ ├── 20210109120245_SeedData.Designer.cs
│ ├── 20210109120245_SeedData.cs
│ ├── 20210204060838_CreatingIdentityTables.Designer.cs
│ ├── 20210204060838_CreatingIdentityTables.cs
│ ├── 20210204062338_AddedRolesToDb.Designer.cs
│ ├── 20210204062338_AddedRolesToDb.cs
│ └── CompanyEmployeeDbContextModelSnapshot.cs
├── Program.cs
├── Properties
│ └── launchSettings.json
├── Startup.cs
├── appsettings.Development.json
├── appsettings.json
└── nlog.config
├── CompanyEmployee.sln
├── Contracts
├── Contracts.csproj
└── IServices
│ ├── IAuthenticationManager.cs
│ ├── ICompanyRepository.cs
│ ├── IDataShaper.cs
│ ├── IEmployeeRepository.cs
│ ├── ILoggerManager.cs
│ ├── IRepositoryBase.cs
│ └── IRepositoryManager.cs
├── Entities
├── CompanyEmployeeDbContext.cs
├── Configuration
│ ├── CompanyConfiguration.cs
│ ├── EmployeeConfiguration.cs
│ ├── IdentityUserLoginConfiquration.cs
│ └── RoleConfiguration.cs
├── DataTransferObjects
│ ├── CompanyDto.cs
│ ├── CompanyForCreationDto.cs
│ ├── CompanyForUpdateDto.cs
│ ├── EmployeeDto.cs
│ ├── EmployeeForCreationDto.cs
│ ├── EmployeeForManipulationDto.cs
│ ├── EmployeeForUpdateDto.cs
│ ├── UserForAuthenticationDto.cs
│ └── UserForRegistrationDto.cs
├── Entities.csproj
├── ErrorModel
│ └── ErrorDetails.cs
├── Models
│ ├── Company.cs
│ ├── Employee.cs
│ └── User.cs
└── RequestFeatures
│ ├── MetaData.cs
│ ├── PagedList.cs
│ └── RequestParameters.cs
├── LoggerService
├── LoggerManager.cs
└── LoggerService.csproj
├── README.md
├── Repository
├── AuthenticationManager.cs
├── DataShaping
│ └── DataShaper.cs
├── Extensions
│ └── RepositoryEmployeeExtensions.cs
├── Repositories
│ ├── CompanyRepository.cs
│ ├── EmployeeRepository.cs
│ ├── RepositoryBase.cs
│ └── RepositoryManager.cs
└── Repository.csproj
└── img
└── ASPNETCore5.0WebAPI.jpg
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 | artifacts/
58 |
59 | # StyleCop
60 | StyleCopReport.xml
61 |
62 | # Files built by Visual Studio
63 | *_i.c
64 | *_p.c
65 | *_h.h
66 | *.ilk
67 | *.meta
68 | *.obj
69 | *.iobj
70 | *.pch
71 | *.pdb
72 | *.ipdb
73 | *.pgc
74 | *.pgd
75 | *.rsp
76 | *.sbr
77 | *.tlb
78 | *.tli
79 | *.tlh
80 | *.tmp
81 | *.tmp_proj
82 | *_wpftmp.csproj
83 | *.log
84 | *.vspscc
85 | *.vssscc
86 | .builds
87 | *.pidb
88 | *.svclog
89 | *.scc
90 |
91 | # Chutzpah Test files
92 | _Chutzpah*
93 |
94 | # Visual C++ cache files
95 | ipch/
96 | *.aps
97 | *.ncb
98 | *.opendb
99 | *.opensdf
100 | *.sdf
101 | *.cachefile
102 | *.VC.db
103 | *.VC.VC.opendb
104 |
105 | # Visual Studio profiler
106 | *.psess
107 | *.vsp
108 | *.vspx
109 | *.sap
110 |
111 | # Visual Studio Trace Files
112 | *.e2e
113 |
114 | # TFS 2012 Local Workspace
115 | $tf/
116 |
117 | # Guidance Automation Toolkit
118 | *.gpState
119 |
120 | # ReSharper is a .NET coding add-in
121 | _ReSharper*/
122 | *.[Rr]e[Ss]harper
123 | *.DotSettings.user
124 |
125 | # JustCode is a .NET coding add-in
126 | .JustCode
127 |
128 | # TeamCity is a build add-in
129 | _TeamCity*
130 |
131 | # DotCover is a Code Coverage Tool
132 | *.dotCover
133 |
134 | # AxoCover is a Code Coverage Tool
135 | .axoCover/*
136 | !.axoCover/settings.json
137 |
138 | # Visual Studio code coverage results
139 | *.coverage
140 | *.coveragexml
141 |
142 | # NCrunch
143 | _NCrunch_*
144 | .*crunch*.local.xml
145 | nCrunchTemp_*
146 |
147 | # MightyMoose
148 | *.mm.*
149 | AutoTest.Net/
150 |
151 | # Web workbench (sass)
152 | .sass-cache/
153 |
154 | # Installshield output folder
155 | [Ee]xpress/
156 |
157 | # DocProject is a documentation generator add-in
158 | DocProject/buildhelp/
159 | DocProject/Help/*.HxT
160 | DocProject/Help/*.HxC
161 | DocProject/Help/*.hhc
162 | DocProject/Help/*.hhk
163 | DocProject/Help/*.hhp
164 | DocProject/Help/Html2
165 | DocProject/Help/html
166 |
167 | # Click-Once directory
168 | publish/
169 |
170 | # Publish Web Output
171 | *.[Pp]ublish.xml
172 | *.azurePubxml
173 | # Note: Comment the next line if you want to checkin your web deploy settings,
174 | # but database connection strings (with potential passwords) will be unencrypted
175 | *.pubxml
176 | *.publishproj
177 |
178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
179 | # checkin your Azure Web App publish settings, but sensitive information contained
180 | # in these scripts will be unencrypted
181 | PublishScripts/
182 |
183 | # NuGet Packages
184 | *.nupkg
185 | # The packages folder can be ignored because of Package Restore
186 | **/[Pp]ackages/*
187 | # except build/, which is used as an MSBuild target.
188 | !**/[Pp]ackages/build/
189 | # Uncomment if necessary however generally it will be regenerated when needed
190 | #!**/[Pp]ackages/repositories.config
191 | # NuGet v3's project.json files produces more ignorable files
192 | *.nuget.props
193 | *.nuget.targets
194 |
195 | # Microsoft Azure Build Output
196 | csx/
197 | *.build.csdef
198 |
199 | # Microsoft Azure Emulator
200 | ecf/
201 | rcf/
202 |
203 | # Windows Store app package directories and files
204 | AppPackages/
205 | BundleArtifacts/
206 | Package.StoreAssociation.xml
207 | _pkginfo.txt
208 | *.appx
209 |
210 | # Visual Studio cache files
211 | # files ending in .cache can be ignored
212 | *.[Cc]ache
213 | # but keep track of directories ending in .cache
214 | !?*.[Cc]ache/
215 |
216 | # Others
217 | ClientBin/
218 | ~$*
219 | *~
220 | *.dbmdl
221 | *.dbproj.schemaview
222 | *.jfm
223 | *.pfx
224 | *.publishsettings
225 | orleans.codegen.cs
226 |
227 | # Including strong name files can present a security risk
228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
229 | #*.snk
230 |
231 | # Since there are multiple workflows, uncomment next line to ignore bower_components
232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
233 | #bower_components/
234 |
235 | # RIA/Silverlight projects
236 | Generated_Code/
237 |
238 | # Backup & report files from converting an old project file
239 | # to a newer Visual Studio version. Backup files are not needed,
240 | # because we have git ;-)
241 | _UpgradeReport_Files/
242 | Backup*/
243 | UpgradeLog*.XML
244 | UpgradeLog*.htm
245 | ServiceFabricBackup/
246 | *.rptproj.bak
247 |
248 | # SQL Server files
249 | *.mdf
250 | *.ldf
251 | *.ndf
252 |
253 | # Business Intelligence projects
254 | *.rdl.data
255 | *.bim.layout
256 | *.bim_*.settings
257 | *.rptproj.rsuser
258 | *- Backup*.rdl
259 |
260 | # Microsoft Fakes
261 | FakesAssemblies/
262 |
263 | # GhostDoc plugin setting file
264 | *.GhostDoc.xml
265 |
266 | # Node.js Tools for Visual Studio
267 | .ntvs_analysis.dat
268 | node_modules/
269 |
270 | # Visual Studio 6 build log
271 | *.plg
272 |
273 | # Visual Studio 6 workspace options file
274 | *.opt
275 |
276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
277 | *.vbw
278 |
279 | # Visual Studio LightSwitch build output
280 | **/*.HTMLClient/GeneratedArtifacts
281 | **/*.DesktopClient/GeneratedArtifacts
282 | **/*.DesktopClient/ModelManifest.xml
283 | **/*.Server/GeneratedArtifacts
284 | **/*.Server/ModelManifest.xml
285 | _Pvt_Extensions
286 |
287 | # Paket dependency manager
288 | .paket/paket.exe
289 | paket-files/
290 |
291 | # FAKE - F# Make
292 | .fake/
293 |
294 | # JetBrains Rider
295 | .idea/
296 | *.sln.iml
297 |
298 | # CodeRush personal settings
299 | .cr/personal
300 |
301 | # Python Tools for Visual Studio (PTVS)
302 | __pycache__/
303 | *.pyc
304 |
305 | # Cake - Uncomment if you are using it
306 | # tools/**
307 | # !tools/packages.config
308 |
309 | # Tabs Studio
310 | *.tss
311 |
312 | # Telerik's JustMock configuration file
313 | *.jmconfig
314 |
315 | # BizTalk build output
316 | *.btp.cs
317 | *.btm.cs
318 | *.odx.cs
319 | *.xsd.cs
320 |
321 | # OpenCover UI analysis results
322 | OpenCover/
323 |
324 | # Azure Stream Analytics local run output
325 | ASALocalRun/
326 |
327 | # MSBuild Binary and Structured Log
328 | *.binlog
329 |
330 | # NVidia Nsight GPU debugger configuration file
331 | *.nvuser
332 |
333 | # MFractors (Xamarin productivity tool) working folder
334 | .mfractor/
335 |
336 | # Local History for Visual Studio
337 | .localhistory/
338 |
339 | # BeatPulse healthcheck temp database
340 | healthchecksdb
--------------------------------------------------------------------------------
/ASP.NETCore5.0WebAPI.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ZahraBayatgh/ASP.NET-Core-5.0-Web-API/94535af56e7664b66eb04449fdced86f0a75a959/ASP.NETCore5.0WebAPI.pdf
--------------------------------------------------------------------------------
/CompanyEmployee.API/CompanyEmployee.API.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net5.0
5 |
6 |
7 |
8 | D:\Projects\CompanyEmployee\CompanyEmployee.API\CompanyEmployee.API.xml
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | all
24 | runtime; build; native; contentfiles; analyzers; buildtransitive
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/CompanyEmployee.API.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CompanyEmployee.API
5 |
6 |
7 |
8 |
9 | Gets the list of all companies
10 |
11 | The companies list
12 |
13 |
14 |
15 | Creates a newly created company
16 |
17 |
18 | A newly created company
19 | Returns the newly created item
20 | If the item is null
21 | If the model is invalid
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Controllers/AuthenticationController.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using CompanyEmployee.API.Infrastructure.ActionFilters;
3 | using Contracts.IServices;
4 | using Entities.DataTransferObjects;
5 | using Entities.Models;
6 | using Microsoft.AspNetCore.Identity;
7 | using Microsoft.AspNetCore.Mvc;
8 | using System.Threading.Tasks;
9 |
10 | namespace CompanyEmployee.API.Controllers
11 | {
12 | [Route("api/authentication")]
13 | [ApiController]
14 | public class AuthenticationController : ControllerBase
15 | {
16 | private readonly ILoggerManager _logger;
17 | private readonly IMapper _mapper;
18 | private readonly UserManager _userManager;
19 | private readonly IAuthenticationManager _authManager;
20 |
21 | public AuthenticationController(ILoggerManager logger, IMapper mapper, UserManager userManager, IAuthenticationManager authManager)
22 | {
23 | _logger = logger;
24 | _mapper = mapper;
25 | _userManager = userManager;
26 | _authManager = authManager;
27 | }
28 |
29 | [HttpPost("login")]
30 | [ServiceFilter(typeof(ValidationFilterAttribute))]
31 | public async Task AuthenticateAsync([FromBody] UserForAuthenticationDto user)
32 | {
33 | if (!await _authManager.ValidateUserAsync(user))
34 | {
35 | _logger.LogWarn($"{nameof(AuthenticateAsync)}: Authentication failed. Wrong user name or password.");
36 |
37 | return Unauthorized();
38 | }
39 |
40 | return Ok(new { Token = await _authManager.CreateTokenAsync() });
41 | }
42 |
43 | [HttpPost]
44 | [ServiceFilter(typeof(ValidationFilterAttribute))]
45 | public async Task RegisterUserAsync([FromBody] UserForRegistrationDto userForRegistration)
46 | {
47 | var user = _mapper.Map(userForRegistration);
48 | var result = await _userManager.CreateAsync(user, userForRegistration.Password);
49 |
50 | if (!result.Succeeded)
51 | {
52 | foreach (var error in result.Errors)
53 | {
54 | ModelState.TryAddModelError(error.Code, error.Description);
55 | }
56 |
57 | return BadRequest(ModelState);
58 | }
59 |
60 | await _userManager.AddToRolesAsync(user, userForRegistration.Roles);
61 |
62 | return StatusCode(201);
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Controllers/CompaniesController.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using CompanyEmployee.API.Infrastructure.ActionFilters;
3 | using CompanyEmployee.API.Infrastructure.ModelBinders;
4 | using Contracts.IServices;
5 | using Entities.DataTransferObjects;
6 | using Entities.Models;
7 | using Microsoft.AspNetCore.Mvc;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Linq;
11 | using System.Threading.Tasks;
12 | using Marvin.Cache.Headers;
13 | using Microsoft.AspNetCore.Authorization;
14 |
15 | namespace CompanyEmployee.API.Controllers
16 | {
17 | [Route("api/companies")]
18 | [ResponseCache(CacheProfileName = "120SecondsDuration")]
19 | [ApiController]
20 | [ApiExplorerSettings(GroupName = "v1")]
21 | public class CompaniesController : ControllerBase
22 | {
23 | private readonly IRepositoryManager _repository;
24 | private readonly ILoggerManager _logger;
25 | private readonly IMapper _mapper;
26 |
27 | public CompaniesController(IRepositoryManager repository, ILoggerManager logger,
28 | IMapper mapper)
29 | {
30 | _repository = repository;
31 | _logger = logger;
32 | _mapper = mapper;
33 | }
34 |
35 | ///
36 | /// Gets the list of all companies
37 | ///
38 | /// The companies list
39 | [HttpGet(Name = "GetCompanies"), Authorize(Roles = "Manager")]
40 | public async Task GetCompaniesAsync()
41 | {
42 | var companies = await _repository.Company.GetAllCompaniesAsync(trackChanges:
43 | false);
44 |
45 | var companiesDto = _mapper.Map>(companies);
46 |
47 | return Ok(companiesDto);
48 | }
49 |
50 | [HttpGet("{id}", Name = "CompanyById")]
51 | [HttpCacheExpiration(CacheLocation = CacheLocation.Public, MaxAge = 60)]
52 | [HttpCacheValidation(MustRevalidate = false)]
53 | public async Task GetCompanyAsync(Guid id)
54 | {
55 | var company = await _repository.Company.GetCompanyAsync(id, trackChanges: false);
56 |
57 | if (company == null)
58 | {
59 | _logger.LogInfo($"Company with id: {id} doesn't exist in the database.");
60 |
61 | return NotFound();
62 | }
63 | else
64 | {
65 | var companyDto = _mapper.Map(company);
66 |
67 | return Ok(companyDto);
68 | }
69 | }
70 |
71 | [HttpGet("collection/({ids})", Name = "CompanyCollection")]
72 | public async Task GetCompanyCollectionAsync([ModelBinder(BinderType =
73 | typeof(ArrayModelBinder))]IEnumerable ids)
74 | {
75 | if (ids == null)
76 | {
77 | _logger.LogError("Parameter ids is null");
78 |
79 | return BadRequest("Parameter ids is null");
80 | }
81 |
82 | var companyEntities = await _repository.Company.GetByIdsAsync(ids, trackChanges:
83 | false);
84 |
85 | if (ids.Count() != companyEntities.Count())
86 | {
87 | _logger.LogError("Some ids are not valid in a collection");
88 |
89 | return NotFound();
90 | }
91 |
92 | var companiesToReturn = _mapper.Map>(companyEntities);
93 |
94 | return Ok(companiesToReturn);
95 | }
96 |
97 | ///
98 | /// Creates a newly created company
99 | ///
100 | ///
101 | /// A newly created company
102 | /// Returns the newly created item
103 | /// If the item is null
104 | /// If the model is invalid
105 | [HttpPost]
106 | [ProducesResponseType(201)]
107 | [ProducesResponseType(400)]
108 | [ProducesResponseType(422)]
109 | [ServiceFilter(typeof(ValidationFilterAttribute))]
110 | public async Task CreateCompanyAsync([FromBody]CompanyForCreationDto
111 | company)
112 | {
113 | var companyEntity = _mapper.Map(company);
114 | _repository.Company.CreateCompany(companyEntity);
115 |
116 | await _repository.SaveAsync();
117 |
118 | var companyToReturn = _mapper.Map(companyEntity);
119 |
120 | return CreatedAtRoute("CompanyById", new { id = companyToReturn.Id },
121 | companyToReturn);
122 | }
123 |
124 | [HttpPost("collection")]
125 | public async Task CreateCompanyCollectionAsync([FromBody]
126 | IEnumerable companyCollection)
127 | {
128 | if (companyCollection == null)
129 | {
130 | _logger.LogError("Company collection sent from client is null.");
131 |
132 | return BadRequest("Company collection is null");
133 | }
134 |
135 | var companyEntities = _mapper.Map>(companyCollection);
136 |
137 | foreach (var company in companyEntities)
138 | {
139 | _repository.Company.CreateCompany(company);
140 | }
141 |
142 | await _repository.SaveAsync();
143 | var companyCollectionToReturn =
144 | _mapper.Map>(companyEntities);
145 | var ids = string.Join(",", companyCollectionToReturn.Select(c => c.Id));
146 |
147 | return CreatedAtRoute("CompanyCollection", new { ids },
148 | companyCollectionToReturn);
149 | }
150 |
151 | [HttpDelete("{id}")]
152 | public async Task DeleteCompanyAsync(Guid id)
153 | {
154 | var company = await _repository.Company.GetCompanyAsync(id, trackChanges: false);
155 |
156 | if (company == null)
157 | {
158 | _logger.LogInfo($"Company with id: {id} doesn't exist in the database.");
159 |
160 | return NotFound();
161 | }
162 |
163 | _repository.Company.DeleteCompany(company);
164 | await _repository.SaveAsync();
165 |
166 | return NoContent();
167 | }
168 |
169 | [HttpPut("{id}")]
170 | [ServiceFilter(typeof(ValidationFilterAttribute))]
171 | public async Task UpdateCompanyAsync(Guid id, [FromBody] CompanyForUpdateDto
172 | company)
173 | {
174 | var companyEntity = await _repository.Company.GetCompanyAsync(id, trackChanges:
175 | true);
176 |
177 | if (companyEntity == null)
178 | {
179 | _logger.LogInfo($"Company with id: {id} doesn't exist in the database.");
180 |
181 | return NotFound();
182 | }
183 |
184 | _mapper.Map(company, companyEntity);
185 | await _repository.SaveAsync();
186 |
187 | return NoContent();
188 | }
189 |
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Controllers/CompaniesV2Controller.cs:
--------------------------------------------------------------------------------
1 | using Contracts.IServices;
2 | using Microsoft.AspNetCore.Mvc;
3 | using System.Threading.Tasks;
4 |
5 | namespace CompanyEmployee.API.Controllers
6 | {
7 | [Route("api/companies")]
8 | [ApiController]
9 | [ApiExplorerSettings(GroupName = "v2")]
10 | public class CompaniesV2Controller : ControllerBase
11 | {
12 | private readonly IRepositoryManager _repository;
13 |
14 | public CompaniesV2Controller(IRepositoryManager repository)
15 | {
16 | _repository = repository;
17 | }
18 |
19 | [HttpGet]
20 | public async Task GetCompanies()
21 | {
22 | var companies = await _repository.Company.GetAllCompaniesAsync(trackChanges:
23 | false);
24 |
25 | return Ok(companies);
26 | }
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Controllers/EmployeesController.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using Contracts.IServices;
3 | using CompanyEmployee.API.Infrastructure.ActionFilters;
4 | using Entities.DataTransferObjects;
5 | using Entities.Models;
6 | using Microsoft.AspNetCore.JsonPatch;
7 | using Microsoft.AspNetCore.Mvc;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Threading.Tasks;
11 | using Entities.RequestFeatures;
12 | using Newtonsoft.Json;
13 |
14 | namespace CompanyEmployee.API.Controllers
15 | {
16 | [Route("api/companies/{companyId}/employees")]
17 | [ApiController]
18 | public class EmployeesController : ControllerBase
19 | {
20 | private readonly IRepositoryManager _repository;
21 | private readonly ILoggerManager _logger;
22 | private readonly IMapper _mapper;
23 | private readonly IDataShaper _dataShaper;
24 | public EmployeesController(IRepositoryManager repository, ILoggerManager logger, IMapper mapper, IDataShaper dataShaper)
25 | {
26 | _repository = repository;
27 | _logger = logger;
28 | _mapper = mapper;
29 | _dataShaper = dataShaper;
30 | }
31 |
32 | [HttpGet(Name = "GetEmployeeForCompany")]
33 | public async Task GetEmployeesForCompanyAsync(Guid companyId, [FromQuery] EmployeeParameters employeeParameters)
34 | {
35 | var company = await _repository.Company.GetCompanyAsync(companyId, trackChanges: false);
36 |
37 | if (!employeeParameters.ValidAgeRange)
38 | return BadRequest("Max age can't be less than min age.");
39 |
40 | if (company == null)
41 | {
42 | _logger.LogInfo($"Company with id: {companyId} doesn't exist in the database.");
43 |
44 | return NotFound();
45 | }
46 |
47 | var employeesFromDb = await _repository.Employee.GetEmployeesAsync(companyId,
48 | employeeParameters, trackChanges: false);
49 |
50 | Response.Headers.Add("X-Pagination",
51 | JsonConvert.SerializeObject(employeesFromDb.MetaData));
52 |
53 | var employeesDto = _mapper.Map>(employeesFromDb);
54 |
55 | return Ok(_dataShaper.ShapeData(employeesDto, employeeParameters.Fields));
56 |
57 | }
58 |
59 | [HttpGet("{id}")]
60 | public async Task GetEmployeeForCompanyAsync(Guid companyId, Guid id)
61 | {
62 | var company = await _repository.Company.GetCompanyAsync(companyId, trackChanges: false);
63 |
64 | if (company == null)
65 | {
66 | _logger.LogInfo($"Company with id: {companyId} doesn't exist in the database.");
67 |
68 | return NotFound();
69 | }
70 |
71 | var employeeDb = await _repository.Employee.GetEmployeeAsync(companyId, id, trackChanges: false);
72 |
73 | if (employeeDb == null)
74 | {
75 | _logger.LogInfo($"Employee with id: {id} doesn't exist in the database.");
76 |
77 | return NotFound();
78 | }
79 |
80 | var employee = _mapper.Map(employeeDb);
81 |
82 | return Ok(employee);
83 | }
84 |
85 | [HttpPost]
86 | public async Task CreateEmployeeForCompanyAsync(Guid companyId, [FromBody]
87 | EmployeeForCreationDto employee)
88 | {
89 | if (employee == null)
90 | {
91 | _logger.LogError("EmployeeForCreationDto object sent from client is null.");
92 |
93 | return BadRequest("EmployeeForCreationDto object is null");
94 | }
95 |
96 | if (!ModelState.IsValid)
97 | {
98 | _logger.LogError("Invalid model state for the EmployeeForCreationDto object");
99 |
100 | return UnprocessableEntity(ModelState);
101 | }
102 |
103 | var company = await _repository.Company.GetCompanyAsync(companyId, trackChanges: false);
104 |
105 | if (company == null)
106 | {
107 | _logger.LogInfo($"Company with id: {companyId} doesn't exist in the database.");
108 |
109 | return NotFound();
110 | }
111 |
112 | var employeeEntity = _mapper.Map(employee);
113 | _repository.Employee.CreateEmployeeForCompany(companyId, employeeEntity);
114 |
115 | await _repository.SaveAsync();
116 |
117 | var employeeToReturn = _mapper.Map(employeeEntity);
118 |
119 | return
120 | CreatedAtRoute("GetEmployeeForCompany",
121 | new
122 | {
123 | companyId,
124 | id = employeeToReturn.Id
125 | },
126 | employeeToReturn);
127 | }
128 |
129 | [HttpDelete("{id}")]
130 | [ServiceFilter(typeof(ValidateEmployeeForCompanyExistsAttribute))]
131 | public async Task DeleteEmployeeForCompanyAsync(Guid companyId, Guid id)
132 | {
133 | var employeeForCompany = HttpContext.Items["employee"] as Employee;
134 | _repository.Employee.DeleteEmployee(employeeForCompany);
135 |
136 | await _repository.SaveAsync();
137 |
138 | return NoContent();
139 | }
140 |
141 | [HttpPut("{id}")]
142 | [ServiceFilter(typeof(ValidationFilterAttribute))]
143 | [ServiceFilter(typeof(ValidateEmployeeForCompanyExistsAttribute))]
144 | public async Task UpdateEmployeeForCompanyAsync(Guid companyId, Guid id, [FromBody] EmployeeForUpdateDto employee)
145 | {
146 | var employeeEntity = HttpContext.Items["employee"] as Employee;
147 | _mapper.Map(employee, employeeEntity);
148 |
149 | await _repository.SaveAsync();
150 |
151 | return NoContent();
152 | }
153 |
154 | [HttpPatch("{id}")]
155 | [ServiceFilter(typeof(ValidateEmployeeForCompanyExistsAttribute))]
156 | public async Task PartiallyUpdateEmployeeForCompanyAsync(Guid companyId, Guid id, [FromBody] JsonPatchDocument patchDoc)
157 | {
158 | if (patchDoc == null)
159 | {
160 | _logger.LogError("patchDoc object sent from client is null.");
161 |
162 | return BadRequest("patchDoc object is null");
163 | }
164 |
165 | var employeeEntity = HttpContext.Items["employee"] as Employee;
166 | var employeeToPatch = _mapper.Map(employeeEntity);
167 |
168 | patchDoc.ApplyTo(employeeToPatch, ModelState);
169 | TryValidateModel(employeeToPatch);
170 |
171 | if (!ModelState.IsValid)
172 | {
173 | _logger.LogError("Invalid model state for the patch document");
174 |
175 | return UnprocessableEntity(ModelState);
176 | }
177 |
178 | _mapper.Map(employeeToPatch, employeeEntity);
179 | await _repository.SaveAsync();
180 |
181 | return NoContent();
182 | }
183 |
184 | }
185 |
186 | }
187 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Controllers/WeatherForecastController.cs:
--------------------------------------------------------------------------------
1 | using Contracts.IServices;
2 | using Microsoft.AspNetCore.Mvc;
3 | using System.Collections.Generic;
4 |
5 | namespace CompanyEmployee.API.Controllers
6 | {
7 | [Route("[controller]")]
8 | [ApiController]
9 | public class WeatherForecastController : ControllerBase
10 | {
11 | private ILoggerManager _logger;
12 | public WeatherForecastController(ILoggerManager logger)
13 | {
14 | _logger = logger;
15 | }
16 | [HttpGet]
17 | public IEnumerable Get()
18 | {
19 | _logger.LogInfo("Here is info message from our values controller.");
20 | _logger.LogDebug("Here is debug message from our values controller.");
21 | _logger.LogWarn("Here is warn message from our values controller.");
22 | _logger.LogError("Here is an error message from our values controller.");
23 |
24 | return new string[] { "value1", "value2" };
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/ActionFilters/ValidateCompanyExistsAttribute.cs:
--------------------------------------------------------------------------------
1 | using Contracts.IServices;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 | using System;
5 | using System.Threading.Tasks;
6 |
7 | namespace CompanyEmployee.API.Infrastructure.ActionFilters
8 | {
9 | public class ValidateCompanyExistsAttribute : IAsyncActionFilter
10 | {
11 | private readonly IRepositoryManager _repository;
12 | private readonly ILoggerManager _logger;
13 |
14 | public ValidateCompanyExistsAttribute(IRepositoryManager repository,
15 | ILoggerManager logger)
16 | {
17 | _repository = repository;
18 | _logger = logger;
19 | }
20 |
21 | public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
22 | {
23 | var trackChanges = context.HttpContext.Request.Method.Equals("PUT");
24 | var id = (Guid)context.ActionArguments["id"];
25 |
26 | var company = await _repository.Company.GetCompanyAsync(id, trackChanges);
27 |
28 | if (company == null)
29 | {
30 | _logger.LogInfo($"Company with id: {id} doesn't exist in the database.");
31 | context.Result = new NotFoundResult();
32 | }
33 | else
34 | {
35 | context.HttpContext.Items.Add("company", company);
36 | await next();
37 | }
38 | }
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/ActionFilters/ValidateEmployeeForCompanyExistsAttribute.cs:
--------------------------------------------------------------------------------
1 | using Contracts.IServices;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 | using System;
5 | using System.Threading.Tasks;
6 |
7 | namespace CompanyEmployee.API.Infrastructure.ActionFilters
8 | {
9 | public class ValidateEmployeeForCompanyExistsAttribute : IAsyncActionFilter
10 | {
11 | private readonly IRepositoryManager _repository;
12 | private readonly ILoggerManager _logger;
13 |
14 | public ValidateEmployeeForCompanyExistsAttribute(IRepositoryManager repository, ILoggerManager logger)
15 | {
16 | _repository = repository;
17 | _logger = logger;
18 | }
19 |
20 | public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
21 | {
22 | var method = context.HttpContext.Request.Method;
23 | var trackChanges = (method.Equals("PUT") || method.Equals("PATCH")) ? true : false;
24 |
25 | var companyId = (Guid)context.ActionArguments["companyId"];
26 | var company = await _repository.Company.GetCompanyAsync(companyId, false);
27 |
28 | if (company == null)
29 | {
30 | _logger.LogInfo($"Company with id: {companyId} doesn't exist in the database.");
31 | context.Result = new NotFoundResult();
32 |
33 | return;
34 | }
35 |
36 | var id = (Guid)context.ActionArguments["id"];
37 | var employee = await _repository.Employee.GetEmployeeAsync(companyId, id,
38 | trackChanges);
39 |
40 | if (employee == null)
41 | {
42 | _logger.LogInfo($"Employee with id: {id} doesn't exist in the database.");
43 | context.Result = new NotFoundResult();
44 | }
45 | else
46 | {
47 | context.HttpContext.Items.Add("employee", employee);
48 | await next();
49 | }
50 | }
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/ActionFilters/ValidationFilterAttribute.cs:
--------------------------------------------------------------------------------
1 | using Contracts.IServices;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 | using System.Linq;
5 |
6 | namespace CompanyEmployee.API.Infrastructure.ActionFilters
7 | {
8 | public class ValidationFilterAttribute : IActionFilter
9 | {
10 | private readonly ILoggerManager _logger;
11 | public ValidationFilterAttribute(ILoggerManager logger)
12 | {
13 | _logger = logger;
14 | }
15 |
16 | public void OnActionExecuting(ActionExecutingContext context)
17 | {
18 | var action = context.RouteData.Values["action"];
19 | var controller = context.RouteData.Values["controller"];
20 | var param = context.ActionArguments
21 | .SingleOrDefault(x => x.Value.ToString().Contains("Dto")).Value;
22 |
23 | if (param == null)
24 | {
25 | _logger.LogError($"Object sent from client is null. Controller: {controller}, action: {action} ");
26 |
27 | context.Result = new BadRequestObjectResult($"Object is null. Controller:{ controller}, action: {action} ");
28 |
29 | return;
30 | }
31 |
32 | if (!context.ModelState.IsValid)
33 | {
34 | _logger.LogError($"Invalid model state for the object. Controller: {controller}, action: {action} ");
35 |
36 | context.Result = new UnprocessableEntityObjectResult(context.ModelState);
37 | }
38 | }
39 |
40 | public void OnActionExecuted(ActionExecutedContext context) { }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/CsvOutputFormatter.cs:
--------------------------------------------------------------------------------
1 | using Entities.DataTransferObjects;
2 | using Microsoft.AspNetCore.Http;
3 | using Microsoft.AspNetCore.Mvc.Formatters;
4 | using Microsoft.Net.Http.Headers;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace CompanyEmployee.API.Infrastructure
11 | {
12 | public class CsvOutputFormatter : TextOutputFormatter
13 | {
14 | public CsvOutputFormatter()
15 | {
16 | SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv"));
17 | SupportedEncodings.Add(Encoding.UTF8);
18 | SupportedEncodings.Add(Encoding.Unicode);
19 | }
20 | protected override bool CanWriteType(Type type)
21 | {
22 | if (typeof(CompanyDto).IsAssignableFrom(type) ||
23 | typeof(IEnumerable).IsAssignableFrom(type))
24 | {
25 | return base.CanWriteType(type);
26 | }
27 |
28 | return false;
29 | }
30 |
31 | public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext
32 | context, Encoding selectedEncoding)
33 | {
34 | var response = context.HttpContext.Response;
35 | var buffer = new StringBuilder();
36 |
37 | if (context.Object is IEnumerable)
38 | {
39 | foreach (var company in (IEnumerable)context.Object)
40 | {
41 | FormatCsv(buffer, company);
42 | }
43 | }
44 | else
45 | {
46 | FormatCsv(buffer, (CompanyDto)context.Object);
47 | }
48 |
49 | await response.WriteAsync(buffer.ToString());
50 | }
51 | private static void FormatCsv(StringBuilder buffer, CompanyDto company)
52 | {
53 | buffer.AppendLine($"{company.Id},\"{company.Name},\"{company.FullAddress}\"");
54 | }
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/Extensions/ExceptionMiddlewareExtensions.cs:
--------------------------------------------------------------------------------
1 | using Contracts.IServices;
2 | using Entities.ErrorModel;
3 | using Microsoft.AspNetCore.Builder;
4 | using Microsoft.AspNetCore.Diagnostics;
5 | using Microsoft.AspNetCore.Http;
6 | using System.Net;
7 |
8 | namespace CompanyEmployee.API.Infrastructure.Extensions
9 | {
10 | public static class ExceptionMiddlewareExtensions
11 | {
12 | public static void ConfigureExceptionHandler(this IApplicationBuilder app,
13 | ILoggerManager logger)
14 | {
15 | app.UseExceptionHandler(appError =>
16 | {
17 | appError.Run(async context =>
18 | {
19 | context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
20 | context.Response.ContentType = "application/json";
21 | var contextFeature = context.Features.Get();
22 | if (contextFeature != null)
23 | {
24 | logger.LogError($"Something went wrong: {contextFeature.Error}");
25 | await context.Response.WriteAsync(new ErrorDetails()
26 | {
27 | StatusCode = context.Response.StatusCode,
28 | Message = "Internal Server Error."
29 | }.ToString());
30 | }
31 | });
32 | });
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/Extensions/ServiceExtensions.cs:
--------------------------------------------------------------------------------
1 | using CompanyEmployee.API.Controllers;
2 | using Contracts.IServices;
3 | using Entities;
4 | using LoggerService;
5 | using Marvin.Cache.Headers;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Mvc;
8 | using Microsoft.EntityFrameworkCore;
9 | using Microsoft.Extensions.Configuration;
10 | using Microsoft.Extensions.DependencyInjection;
11 | using AspNetCoreRateLimit;
12 | using System.Collections.Generic;
13 | using Repository.Repositories;
14 | using Entities.Models;
15 | using Microsoft.AspNetCore.Identity;
16 | using System;
17 | using Microsoft.AspNetCore.Authentication.JwtBearer;
18 | using Microsoft.IdentityModel.Tokens;
19 | using System.Text;
20 | using Microsoft.OpenApi.Models;
21 | using System.IO;
22 | using System.Reflection;
23 |
24 |
25 | namespace CompanyEmployee.API.Infrastructure.Extensions
26 | {
27 | public static class ServiceExtensions
28 | {
29 | public static void ConfigureCors(this IServiceCollection services) =>
30 | services.AddCors(options =>
31 | {
32 | options.AddPolicy("CorsPolicy", builder =>
33 | builder.AllowAnyOrigin()
34 | .AllowAnyMethod()
35 | .AllowAnyHeader());
36 | });
37 |
38 | public static void ConfigureIISIntegration(this IServiceCollection services) =>
39 | services.Configure(options =>
40 | {
41 | });
42 | public static void ConfigureLoggerService(this IServiceCollection services) => services.AddScoped();
43 |
44 | public static void ConfigureSqlContext(this IServiceCollection services,
45 | IConfiguration configuration) =>
46 | services.AddDbContext(opts => opts.UseSqlServer(configuration.GetConnectionString("sqlConnection"), b =>
47 | b.MigrationsAssembly("CompanyEmployee.API")));
48 |
49 | public static void ConfigureRepositoryManager(this IServiceCollection services) =>
50 | services.AddScoped();
51 |
52 | public static IMvcBuilder AddCustomCSVFormatter(this IMvcBuilder builder) =>
53 | builder.AddMvcOptions(config => config.OutputFormatters.Add(new
54 | CsvOutputFormatter()));
55 |
56 | public static void ConfigureVersioning(this IServiceCollection services)
57 | {
58 | services.AddApiVersioning(opt =>
59 | {
60 | opt.ReportApiVersions = true;
61 | opt.AssumeDefaultVersionWhenUnspecified = true;
62 | opt.DefaultApiVersion = new ApiVersion(1, 0);
63 | opt.Conventions.Controller().HasApiVersion(new ApiVersion(1, 0));
64 | opt.Conventions.Controller().HasDeprecatedApiVersion(new ApiVersion(2, 0));
65 | });
66 | }
67 |
68 | public static void ConfigureResponseCaching(this IServiceCollection services) => services.AddResponseCaching();
69 |
70 | public static void ConfigureHttpCacheHeaders(this IServiceCollection services) =>
71 | services.AddHttpCacheHeaders(
72 | (expirationOpt) =>
73 | {
74 | expirationOpt.MaxAge = 65;
75 | expirationOpt.CacheLocation = CacheLocation.Private;
76 | },
77 | (validationOpt) =>
78 | {
79 | validationOpt.MustRevalidate = true;
80 | });
81 |
82 | public static void ConfigureRateLimitingOptions(this IServiceCollection services)
83 | {
84 | var rateLimitRules = new List
85 | {
86 | new RateLimitRule
87 | {
88 | Endpoint = "*",
89 | Limit= 30,
90 | Period = "5m"
91 | }
92 | };
93 | services.Configure(opt =>
94 | {
95 | opt.GeneralRules = rateLimitRules;
96 | });
97 | services.AddSingleton();
98 |
99 | services.AddSingleton();
100 |
101 | services.AddSingleton();
102 | }
103 |
104 | public static void ConfigureIdentity(this IServiceCollection services)
105 | {
106 | var builder = services.AddIdentityCore(o =>
107 | {
108 | o.Password.RequireDigit = true;
109 | o.Password.RequireLowercase = false;
110 | o.Password.RequireUppercase = false;
111 | o.Password.RequireNonAlphanumeric = false;
112 | o.Password.RequiredLength = 10;
113 | o.User.RequireUniqueEmail = true;
114 | });
115 |
116 | builder = new IdentityBuilder(builder.UserType, typeof(IdentityRole),
117 | builder.Services);
118 | builder.AddEntityFrameworkStores()
119 | .AddDefaultTokenProviders();
120 | }
121 |
122 | public static void ConfigureJWT(this IServiceCollection services, IConfiguration configuration)
123 | {
124 | var jwtSettings = configuration.GetSection("JwtSettings");
125 | var secretKey = Environment.GetEnvironmentVariable("SECRET");
126 | services.AddAuthentication(opt =>
127 | {
128 | opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
129 | opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
130 | })
131 | .AddJwtBearer(options =>
132 | {
133 | options.TokenValidationParameters = new TokenValidationParameters
134 | {
135 | ValidateIssuer = true,
136 | ValidateAudience = true,
137 | ValidateLifetime = true,
138 | ValidateIssuerSigningKey = true,
139 | ValidIssuer = jwtSettings.GetSection("validIssuer").Value,
140 | ValidAudience = jwtSettings.GetSection("validAudience").Value,
141 | IssuerSigningKey = new
142 | SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey))
143 | };
144 | });
145 | }
146 | public static void ConfigureSwagger(this IServiceCollection services)
147 | {
148 | services.AddSwaggerGen(s =>
149 | {
150 | s.SwaggerDoc("v1", new OpenApiInfo
151 | {
152 | Title = "CompanyEmployee.API",
153 | Version = "v1",
154 | Description = "CompanyEmployees API by Zahra Bayat",
155 | Contact = new OpenApiContact
156 | {
157 | Name = "Zahra Bayat",
158 | Email = "BytZahra@gmail.com",
159 | Url = new Uri("https://www.linkedin.com/in/zahrabayat"),
160 | },
161 | License = new OpenApiLicense
162 | {
163 | Name = "CompanyEmployees API ",
164 | }
165 | });
166 | s.SwaggerDoc("v2", new OpenApiInfo
167 | {
168 | Title = "CompanyEmployee.API",
169 | Version = "v2"
170 | });
171 | var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
172 | var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
173 | s.IncludeXmlComments(xmlPath);
174 | s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
175 | {
176 | In = ParameterLocation.Header,
177 | Description = "Place to add JWT with Bearer",
178 | Name = "Authorization",
179 | Type = SecuritySchemeType.ApiKey,
180 | Scheme = "Bearer"
181 | });
182 | s.AddSecurityRequirement(new OpenApiSecurityRequirement()
183 | {
184 | {
185 | new OpenApiSecurityScheme
186 | {
187 | Reference = new OpenApiReference
188 | {
189 | Type = ReferenceType.SecurityScheme,
190 | Id = "Bearer"
191 | },
192 | Name = "Bearer",
193 | },
194 | new List()
195 | }
196 | });
197 | });
198 | }
199 |
200 |
201 | }
202 |
203 | }
204 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/MappingProfile.cs:
--------------------------------------------------------------------------------
1 | using AutoMapper;
2 | using Entities.DataTransferObjects;
3 | using Entities.Models;
4 |
5 | namespace CompanyEmployee.API.Infrastructure
6 | {
7 | public class MappingProfile : Profile
8 | {
9 | public MappingProfile()
10 | {
11 | CreateMap()
12 | .ForMember(c => c.FullAddress,
13 | opt => opt.MapFrom(x => string.Join(' ', x.Address, x.Country)));
14 |
15 | CreateMap();
16 |
17 | CreateMap();
18 | CreateMap();
19 | CreateMap().ReverseMap();
20 | CreateMap();
21 | CreateMap();
22 | }
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Infrastructure/ModelBinders/ArrayModelBinder.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc.ModelBinding;
2 | using System;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Threading.Tasks;
7 |
8 | namespace CompanyEmployee.API.Infrastructure.ModelBinders
9 | {
10 | public class ArrayModelBinder : IModelBinder
11 | {
12 | public Task BindModelAsync(ModelBindingContext bindingContext)
13 | {
14 | if (!bindingContext.ModelMetadata.IsEnumerableType)
15 | {
16 | bindingContext.Result = ModelBindingResult.Failed();
17 |
18 | return Task.CompletedTask;
19 | }
20 |
21 | var providedValue = bindingContext.ValueProvider
22 | .GetValue(bindingContext.ModelName)
23 | .ToString();
24 |
25 | if (string.IsNullOrEmpty(providedValue))
26 | {
27 | bindingContext.Result = ModelBindingResult.Success(null);
28 |
29 | return Task.CompletedTask;
30 | }
31 |
32 | var genericType =
33 | bindingContext.ModelType.GetTypeInfo().GenericTypeArguments[0];
34 |
35 | var converter = TypeDescriptor.GetConverter(genericType);
36 | var objectArray = providedValue.Split(new[] { "," },
37 | StringSplitOptions.RemoveEmptyEntries)
38 | .Select(x => converter.ConvertFromString(x.Trim()))
39 | .ToArray();
40 |
41 | var guidArray = Array.CreateInstance(genericType, objectArray.Length);
42 | objectArray.CopyTo(guidArray, 0);
43 | bindingContext.Model = guidArray;
44 |
45 | bindingContext.Result = ModelBindingResult.Success(bindingContext.Model);
46 |
47 | return Task.CompletedTask;
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Migrations/20210109115024_Init.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using Entities;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Metadata;
7 | using Microsoft.EntityFrameworkCore.Migrations;
8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
9 |
10 | namespace CompanyEmployee.API.Migrations
11 | {
12 | [DbContext(typeof(CompanyEmployeeDbContext))]
13 | [Migration("20210109115024_Init")]
14 | partial class Init
15 | {
16 | protected override void BuildTargetModel(ModelBuilder modelBuilder)
17 | {
18 | #pragma warning disable 612, 618
19 | modelBuilder
20 | .UseIdentityColumns()
21 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
22 | .HasAnnotation("ProductVersion", "5.0.1");
23 |
24 | modelBuilder.Entity("Entities.Models.Company", b =>
25 | {
26 | b.Property("Id")
27 | .ValueGeneratedOnAdd()
28 | .HasColumnType("uniqueidentifier")
29 | .HasColumnName("CompanyId");
30 |
31 | b.Property("Address")
32 | .IsRequired()
33 | .HasMaxLength(60)
34 | .HasColumnType("nvarchar(60)");
35 |
36 | b.Property("Country")
37 | .HasColumnType("nvarchar(max)");
38 |
39 | b.Property("Name")
40 | .IsRequired()
41 | .HasMaxLength(60)
42 | .HasColumnType("nvarchar(60)");
43 |
44 | b.HasKey("Id");
45 |
46 | b.ToTable("Companies");
47 | });
48 |
49 | modelBuilder.Entity("Entities.Models.Employee", b =>
50 | {
51 | b.Property("Id")
52 | .ValueGeneratedOnAdd()
53 | .HasColumnType("uniqueidentifier")
54 | .HasColumnName("EmployeeId");
55 |
56 | b.Property("Age")
57 | .HasColumnType("int");
58 |
59 | b.Property("CompanyId")
60 | .HasColumnType("uniqueidentifier");
61 |
62 | b.Property("Name")
63 | .IsRequired()
64 | .HasMaxLength(30)
65 | .HasColumnType("nvarchar(30)");
66 |
67 | b.Property("Position")
68 | .IsRequired()
69 | .HasMaxLength(20)
70 | .HasColumnType("nvarchar(20)");
71 |
72 | b.HasKey("Id");
73 |
74 | b.HasIndex("CompanyId");
75 |
76 | b.ToTable("Employees");
77 | });
78 |
79 | modelBuilder.Entity("Entities.Models.Employee", b =>
80 | {
81 | b.HasOne("Entities.Models.Company", "Company")
82 | .WithMany("Employees")
83 | .HasForeignKey("CompanyId")
84 | .OnDelete(DeleteBehavior.Cascade)
85 | .IsRequired();
86 |
87 | b.Navigation("Company");
88 | });
89 |
90 | modelBuilder.Entity("Entities.Models.Company", b =>
91 | {
92 | b.Navigation("Employees");
93 | });
94 | #pragma warning restore 612, 618
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Migrations/20210109115024_Init.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore.Migrations;
3 |
4 | namespace CompanyEmployee.API.Migrations
5 | {
6 | public partial class Init : Migration
7 | {
8 | protected override void Up(MigrationBuilder migrationBuilder)
9 | {
10 | migrationBuilder.CreateTable(
11 | name: "Companies",
12 | columns: table => new
13 | {
14 | CompanyId = table.Column(type: "uniqueidentifier", nullable: false),
15 | Name = table.Column(type: "nvarchar(60)", maxLength: 60, nullable: false),
16 | Address = table.Column(type: "nvarchar(60)", maxLength: 60, nullable: false),
17 | Country = table.Column(type: "nvarchar(max)", nullable: true)
18 | },
19 | constraints: table =>
20 | {
21 | table.PrimaryKey("PK_Companies", x => x.CompanyId);
22 | });
23 |
24 | migrationBuilder.CreateTable(
25 | name: "Employees",
26 | columns: table => new
27 | {
28 | EmployeeId = table.Column(type: "uniqueidentifier", nullable: false),
29 | Name = table.Column(type: "nvarchar(30)", maxLength: 30, nullable: false),
30 | Age = table.Column(type: "int", nullable: false),
31 | Position = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false),
32 | CompanyId = table.Column(type: "uniqueidentifier", nullable: false)
33 | },
34 | constraints: table =>
35 | {
36 | table.PrimaryKey("PK_Employees", x => x.EmployeeId);
37 | table.ForeignKey(
38 | name: "FK_Employees_Companies_CompanyId",
39 | column: x => x.CompanyId,
40 | principalTable: "Companies",
41 | principalColumn: "CompanyId",
42 | onDelete: ReferentialAction.Cascade);
43 | });
44 |
45 | migrationBuilder.CreateIndex(
46 | name: "IX_Employees_CompanyId",
47 | table: "Employees",
48 | column: "CompanyId");
49 | }
50 |
51 | protected override void Down(MigrationBuilder migrationBuilder)
52 | {
53 | migrationBuilder.DropTable(
54 | name: "Employees");
55 |
56 | migrationBuilder.DropTable(
57 | name: "Companies");
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Migrations/20210109120245_SeedData.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using Entities;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Metadata;
7 | using Microsoft.EntityFrameworkCore.Migrations;
8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
9 |
10 | namespace CompanyEmployee.API.Migrations
11 | {
12 | [DbContext(typeof(CompanyEmployeeDbContext))]
13 | [Migration("20210109120245_SeedData")]
14 | partial class SeedData
15 | {
16 | protected override void BuildTargetModel(ModelBuilder modelBuilder)
17 | {
18 | #pragma warning disable 612, 618
19 | modelBuilder
20 | .UseIdentityColumns()
21 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
22 | .HasAnnotation("ProductVersion", "5.0.1");
23 |
24 | modelBuilder.Entity("Entities.Models.Company", b =>
25 | {
26 | b.Property("Id")
27 | .ValueGeneratedOnAdd()
28 | .HasColumnType("uniqueidentifier")
29 | .HasColumnName("CompanyId");
30 |
31 | b.Property("Address")
32 | .IsRequired()
33 | .HasMaxLength(60)
34 | .HasColumnType("nvarchar(60)");
35 |
36 | b.Property("Country")
37 | .HasColumnType("nvarchar(max)");
38 |
39 | b.Property("Name")
40 | .IsRequired()
41 | .HasMaxLength(60)
42 | .HasColumnType("nvarchar(60)");
43 |
44 | b.HasKey("Id");
45 |
46 | b.ToTable("Companies");
47 |
48 | b.HasData(
49 | new
50 | {
51 | Id = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
52 | Address = "Tehran,Tajrish",
53 | Country = "Iran",
54 | Name = "Raveshmand_Ltd"
55 | },
56 | new
57 | {
58 | Id = new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"),
59 | Address = "London",
60 | Country = "English",
61 | Name = "Geeks_Ltd"
62 | });
63 | });
64 |
65 | modelBuilder.Entity("Entities.Models.Employee", b =>
66 | {
67 | b.Property("Id")
68 | .ValueGeneratedOnAdd()
69 | .HasColumnType("uniqueidentifier")
70 | .HasColumnName("EmployeeId");
71 |
72 | b.Property("Age")
73 | .HasColumnType("int");
74 |
75 | b.Property("CompanyId")
76 | .HasColumnType("uniqueidentifier");
77 |
78 | b.Property("Name")
79 | .IsRequired()
80 | .HasMaxLength(30)
81 | .HasColumnType("nvarchar(30)");
82 |
83 | b.Property("Position")
84 | .IsRequired()
85 | .HasMaxLength(20)
86 | .HasColumnType("nvarchar(20)");
87 |
88 | b.HasKey("Id");
89 |
90 | b.HasIndex("CompanyId");
91 |
92 | b.ToTable("Employees");
93 |
94 | b.HasData(
95 | new
96 | {
97 | Id = new Guid("80abbca8-664d-4b20-b5de-024705497d4a"),
98 | Age = 26,
99 | CompanyId = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
100 | Name = "Zahra Bayat",
101 | Position = "Backend developer"
102 | },
103 | new
104 | {
105 | Id = new Guid("86dba8c0-d178-41e7-938c-ed49778fb52a"),
106 | Age = 30,
107 | CompanyId = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
108 | Name = "Ali Bayat",
109 | Position = "Backend developer"
110 | },
111 | new
112 | {
113 | Id = new Guid("021ca3c1-0deb-4afd-ae94-2159a8479811"),
114 | Age = 35,
115 | CompanyId = new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"),
116 | Name = "Sara Bayat",
117 | Position = "Frontend developer"
118 | });
119 | });
120 |
121 | modelBuilder.Entity("Entities.Models.Employee", b =>
122 | {
123 | b.HasOne("Entities.Models.Company", "Company")
124 | .WithMany("Employees")
125 | .HasForeignKey("CompanyId")
126 | .OnDelete(DeleteBehavior.Cascade)
127 | .IsRequired();
128 |
129 | b.Navigation("Company");
130 | });
131 |
132 | modelBuilder.Entity("Entities.Models.Company", b =>
133 | {
134 | b.Navigation("Employees");
135 | });
136 | #pragma warning restore 612, 618
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Migrations/20210109120245_SeedData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore.Migrations;
3 |
4 | namespace CompanyEmployee.API.Migrations
5 | {
6 | public partial class SeedData : Migration
7 | {
8 | protected override void Up(MigrationBuilder migrationBuilder)
9 | {
10 | migrationBuilder.InsertData(
11 | table: "Companies",
12 | columns: new[] { "CompanyId", "Address", "Country", "Name" },
13 | values: new object[] { new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"), "Tehran,Tajrish", "Iran", "Raveshmand_Ltd" });
14 |
15 | migrationBuilder.InsertData(
16 | table: "Companies",
17 | columns: new[] { "CompanyId", "Address", "Country", "Name" },
18 | values: new object[] { new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"), "London", "English", "Geeks_Ltd" });
19 |
20 | migrationBuilder.InsertData(
21 | table: "Employees",
22 | columns: new[] { "EmployeeId", "Age", "CompanyId", "Name", "Position" },
23 | values: new object[] { new Guid("80abbca8-664d-4b20-b5de-024705497d4a"), 26, new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"), "Zahra Bayat", "Backend developer" });
24 |
25 | migrationBuilder.InsertData(
26 | table: "Employees",
27 | columns: new[] { "EmployeeId", "Age", "CompanyId", "Name", "Position" },
28 | values: new object[] { new Guid("86dba8c0-d178-41e7-938c-ed49778fb52a"), 30, new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"), "Ali Bayat", "Backend developer" });
29 |
30 | migrationBuilder.InsertData(
31 | table: "Employees",
32 | columns: new[] { "EmployeeId", "Age", "CompanyId", "Name", "Position" },
33 | values: new object[] { new Guid("021ca3c1-0deb-4afd-ae94-2159a8479811"), 35, new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"), "Sara Bayat", "Frontend developer" });
34 | }
35 |
36 | protected override void Down(MigrationBuilder migrationBuilder)
37 | {
38 | migrationBuilder.DeleteData(
39 | table: "Employees",
40 | keyColumn: "EmployeeId",
41 | keyValue: new Guid("021ca3c1-0deb-4afd-ae94-2159a8479811"));
42 |
43 | migrationBuilder.DeleteData(
44 | table: "Employees",
45 | keyColumn: "EmployeeId",
46 | keyValue: new Guid("80abbca8-664d-4b20-b5de-024705497d4a"));
47 |
48 | migrationBuilder.DeleteData(
49 | table: "Employees",
50 | keyColumn: "EmployeeId",
51 | keyValue: new Guid("86dba8c0-d178-41e7-938c-ed49778fb52a"));
52 |
53 | migrationBuilder.DeleteData(
54 | table: "Companies",
55 | keyColumn: "CompanyId",
56 | keyValue: new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"));
57 |
58 | migrationBuilder.DeleteData(
59 | table: "Companies",
60 | keyColumn: "CompanyId",
61 | keyValue: new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"));
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Migrations/20210204060838_CreatingIdentityTables.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using Entities;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Metadata;
7 | using Microsoft.EntityFrameworkCore.Migrations;
8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
9 |
10 | namespace CompanyEmployee.API.Migrations
11 | {
12 | [DbContext(typeof(CompanyEmployeeDbContext))]
13 | [Migration("20210204060838_CreatingIdentityTables")]
14 | partial class CreatingIdentityTables
15 | {
16 | protected override void BuildTargetModel(ModelBuilder modelBuilder)
17 | {
18 | #pragma warning disable 612, 618
19 | modelBuilder
20 | .UseIdentityColumns()
21 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
22 | .HasAnnotation("ProductVersion", "5.0.2");
23 |
24 | modelBuilder.Entity("Entities.Models.Company", b =>
25 | {
26 | b.Property("Id")
27 | .ValueGeneratedOnAdd()
28 | .HasColumnType("uniqueidentifier")
29 | .HasColumnName("CompanyId");
30 |
31 | b.Property("Address")
32 | .IsRequired()
33 | .HasMaxLength(60)
34 | .HasColumnType("nvarchar(60)");
35 |
36 | b.Property("Country")
37 | .HasColumnType("nvarchar(max)");
38 |
39 | b.Property("Name")
40 | .IsRequired()
41 | .HasMaxLength(60)
42 | .HasColumnType("nvarchar(60)");
43 |
44 | b.HasKey("Id");
45 |
46 | b.ToTable("Companies");
47 |
48 | b.HasData(
49 | new
50 | {
51 | Id = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
52 | Address = "Tehran,Tajrish",
53 | Country = "Iran",
54 | Name = "Raveshmand_Ltd"
55 | },
56 | new
57 | {
58 | Id = new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"),
59 | Address = "London",
60 | Country = "English",
61 | Name = "Geeks_Ltd"
62 | });
63 | });
64 |
65 | modelBuilder.Entity("Entities.Models.Employee", b =>
66 | {
67 | b.Property("Id")
68 | .ValueGeneratedOnAdd()
69 | .HasColumnType("uniqueidentifier")
70 | .HasColumnName("EmployeeId");
71 |
72 | b.Property("Age")
73 | .HasColumnType("int");
74 |
75 | b.Property("CompanyId")
76 | .HasColumnType("uniqueidentifier");
77 |
78 | b.Property("Name")
79 | .IsRequired()
80 | .HasMaxLength(30)
81 | .HasColumnType("nvarchar(30)");
82 |
83 | b.Property("Position")
84 | .IsRequired()
85 | .HasMaxLength(20)
86 | .HasColumnType("nvarchar(20)");
87 |
88 | b.HasKey("Id");
89 |
90 | b.HasIndex("CompanyId");
91 |
92 | b.ToTable("Employees");
93 |
94 | b.HasData(
95 | new
96 | {
97 | Id = new Guid("80abbca8-664d-4b20-b5de-024705497d4a"),
98 | Age = 26,
99 | CompanyId = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
100 | Name = "Zahra Bayat",
101 | Position = "Backend developer"
102 | },
103 | new
104 | {
105 | Id = new Guid("86dba8c0-d178-41e7-938c-ed49778fb52a"),
106 | Age = 30,
107 | CompanyId = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
108 | Name = "Ali Bayat",
109 | Position = "Backend developer"
110 | },
111 | new
112 | {
113 | Id = new Guid("021ca3c1-0deb-4afd-ae94-2159a8479811"),
114 | Age = 35,
115 | CompanyId = new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"),
116 | Name = "Sara Bayat",
117 | Position = "Frontend developer"
118 | });
119 | });
120 |
121 | modelBuilder.Entity("Entities.Models.User", b =>
122 | {
123 | b.Property("Id")
124 | .HasColumnType("nvarchar(450)");
125 |
126 | b.Property("AccessFailedCount")
127 | .HasColumnType("int");
128 |
129 | b.Property("ConcurrencyStamp")
130 | .IsConcurrencyToken()
131 | .HasColumnType("nvarchar(max)");
132 |
133 | b.Property("Email")
134 | .HasMaxLength(256)
135 | .HasColumnType("nvarchar(256)");
136 |
137 | b.Property("EmailConfirmed")
138 | .HasColumnType("bit");
139 |
140 | b.Property("FirstName")
141 | .HasColumnType("nvarchar(max)");
142 |
143 | b.Property("LastName")
144 | .HasColumnType("nvarchar(max)");
145 |
146 | b.Property("LockoutEnabled")
147 | .HasColumnType("bit");
148 |
149 | b.Property("LockoutEnd")
150 | .HasColumnType("datetimeoffset");
151 |
152 | b.Property("NormalizedEmail")
153 | .HasMaxLength(256)
154 | .HasColumnType("nvarchar(256)");
155 |
156 | b.Property("NormalizedUserName")
157 | .HasMaxLength(256)
158 | .HasColumnType("nvarchar(256)");
159 |
160 | b.Property("PasswordHash")
161 | .HasColumnType("nvarchar(max)");
162 |
163 | b.Property("PhoneNumber")
164 | .HasColumnType("nvarchar(max)");
165 |
166 | b.Property("PhoneNumberConfirmed")
167 | .HasColumnType("bit");
168 |
169 | b.Property("SecurityStamp")
170 | .HasColumnType("nvarchar(max)");
171 |
172 | b.Property("TwoFactorEnabled")
173 | .HasColumnType("bit");
174 |
175 | b.Property("UserName")
176 | .HasMaxLength(256)
177 | .HasColumnType("nvarchar(256)");
178 |
179 | b.HasKey("Id");
180 |
181 | b.HasIndex("NormalizedEmail")
182 | .HasDatabaseName("EmailIndex");
183 |
184 | b.HasIndex("NormalizedUserName")
185 | .IsUnique()
186 | .HasDatabaseName("UserNameIndex")
187 | .HasFilter("[NormalizedUserName] IS NOT NULL");
188 |
189 | b.ToTable("AspNetUsers");
190 | });
191 |
192 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
193 | {
194 | b.Property("Id")
195 | .HasColumnType("nvarchar(450)");
196 |
197 | b.Property("ConcurrencyStamp")
198 | .IsConcurrencyToken()
199 | .HasColumnType("nvarchar(max)");
200 |
201 | b.Property("Name")
202 | .HasMaxLength(256)
203 | .HasColumnType("nvarchar(256)");
204 |
205 | b.Property("NormalizedName")
206 | .HasMaxLength(256)
207 | .HasColumnType("nvarchar(256)");
208 |
209 | b.HasKey("Id");
210 |
211 | b.HasIndex("NormalizedName")
212 | .IsUnique()
213 | .HasDatabaseName("RoleNameIndex")
214 | .HasFilter("[NormalizedName] IS NOT NULL");
215 |
216 | b.ToTable("AspNetRoles");
217 | });
218 |
219 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
220 | {
221 | b.Property("Id")
222 | .ValueGeneratedOnAdd()
223 | .HasColumnType("int")
224 | .UseIdentityColumn();
225 |
226 | b.Property("ClaimType")
227 | .HasColumnType("nvarchar(max)");
228 |
229 | b.Property("ClaimValue")
230 | .HasColumnType("nvarchar(max)");
231 |
232 | b.Property("RoleId")
233 | .IsRequired()
234 | .HasColumnType("nvarchar(450)");
235 |
236 | b.HasKey("Id");
237 |
238 | b.HasIndex("RoleId");
239 |
240 | b.ToTable("AspNetRoleClaims");
241 | });
242 |
243 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
244 | {
245 | b.Property("Id")
246 | .ValueGeneratedOnAdd()
247 | .HasColumnType("int")
248 | .UseIdentityColumn();
249 |
250 | b.Property("ClaimType")
251 | .HasColumnType("nvarchar(max)");
252 |
253 | b.Property("ClaimValue")
254 | .HasColumnType("nvarchar(max)");
255 |
256 | b.Property("UserId")
257 | .IsRequired()
258 | .HasColumnType("nvarchar(450)");
259 |
260 | b.HasKey("Id");
261 |
262 | b.HasIndex("UserId");
263 |
264 | b.ToTable("AspNetUserClaims");
265 | });
266 |
267 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
268 | {
269 | b.Property("LoginProvider")
270 | .HasColumnType("nvarchar(max)");
271 |
272 | b.Property("ProviderDisplayName")
273 | .HasColumnType("nvarchar(max)");
274 |
275 | b.Property("ProviderKey")
276 | .HasColumnType("nvarchar(max)");
277 |
278 | b.Property("UserId")
279 | .HasColumnType("int");
280 |
281 | b.ToTable("IdentityUserLogin");
282 | });
283 |
284 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
285 | {
286 | b.Property("LoginProvider")
287 | .HasColumnType("nvarchar(450)");
288 |
289 | b.Property("ProviderKey")
290 | .HasColumnType("nvarchar(450)");
291 |
292 | b.Property("ProviderDisplayName")
293 | .HasColumnType("nvarchar(max)");
294 |
295 | b.Property("UserId")
296 | .IsRequired()
297 | .HasColumnType("nvarchar(450)");
298 |
299 | b.HasKey("LoginProvider", "ProviderKey");
300 |
301 | b.HasIndex("UserId");
302 |
303 | b.ToTable("AspNetUserLogins");
304 | });
305 |
306 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
307 | {
308 | b.Property("UserId")
309 | .HasColumnType("nvarchar(450)");
310 |
311 | b.Property("RoleId")
312 | .HasColumnType("nvarchar(450)");
313 |
314 | b.HasKey("UserId", "RoleId");
315 |
316 | b.HasIndex("RoleId");
317 |
318 | b.ToTable("AspNetUserRoles");
319 | });
320 |
321 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
322 | {
323 | b.Property("UserId")
324 | .HasColumnType("nvarchar(450)");
325 |
326 | b.Property("LoginProvider")
327 | .HasColumnType("nvarchar(450)");
328 |
329 | b.Property("Name")
330 | .HasColumnType("nvarchar(450)");
331 |
332 | b.Property("Value")
333 | .HasColumnType("nvarchar(max)");
334 |
335 | b.HasKey("UserId", "LoginProvider", "Name");
336 |
337 | b.ToTable("AspNetUserTokens");
338 | });
339 |
340 | modelBuilder.Entity("Entities.Models.Employee", b =>
341 | {
342 | b.HasOne("Entities.Models.Company", "Company")
343 | .WithMany("Employees")
344 | .HasForeignKey("CompanyId")
345 | .OnDelete(DeleteBehavior.Cascade)
346 | .IsRequired();
347 |
348 | b.Navigation("Company");
349 | });
350 |
351 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
352 | {
353 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
354 | .WithMany()
355 | .HasForeignKey("RoleId")
356 | .OnDelete(DeleteBehavior.Cascade)
357 | .IsRequired();
358 | });
359 |
360 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
361 | {
362 | b.HasOne("Entities.Models.User", null)
363 | .WithMany()
364 | .HasForeignKey("UserId")
365 | .OnDelete(DeleteBehavior.Cascade)
366 | .IsRequired();
367 | });
368 |
369 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
370 | {
371 | b.HasOne("Entities.Models.User", null)
372 | .WithMany()
373 | .HasForeignKey("UserId")
374 | .OnDelete(DeleteBehavior.Cascade)
375 | .IsRequired();
376 | });
377 |
378 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
379 | {
380 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
381 | .WithMany()
382 | .HasForeignKey("RoleId")
383 | .OnDelete(DeleteBehavior.Cascade)
384 | .IsRequired();
385 |
386 | b.HasOne("Entities.Models.User", null)
387 | .WithMany()
388 | .HasForeignKey("UserId")
389 | .OnDelete(DeleteBehavior.Cascade)
390 | .IsRequired();
391 | });
392 |
393 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
394 | {
395 | b.HasOne("Entities.Models.User", null)
396 | .WithMany()
397 | .HasForeignKey("UserId")
398 | .OnDelete(DeleteBehavior.Cascade)
399 | .IsRequired();
400 | });
401 |
402 | modelBuilder.Entity("Entities.Models.Company", b =>
403 | {
404 | b.Navigation("Employees");
405 | });
406 | #pragma warning restore 612, 618
407 | }
408 | }
409 | }
410 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Migrations/20210204060838_CreatingIdentityTables.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore.Migrations;
3 |
4 | namespace CompanyEmployee.API.Migrations
5 | {
6 | public partial class CreatingIdentityTables : Migration
7 | {
8 | protected override void Up(MigrationBuilder migrationBuilder)
9 | {
10 | migrationBuilder.CreateTable(
11 | name: "AspNetRoles",
12 | columns: table => new
13 | {
14 | Id = table.Column(type: "nvarchar(450)", nullable: false),
15 | Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
16 | NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
17 | ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true)
18 | },
19 | constraints: table =>
20 | {
21 | table.PrimaryKey("PK_AspNetRoles", x => x.Id);
22 | });
23 |
24 | migrationBuilder.CreateTable(
25 | name: "AspNetUsers",
26 | columns: table => new
27 | {
28 | Id = table.Column(type: "nvarchar(450)", nullable: false),
29 | FirstName = table.Column(type: "nvarchar(max)", nullable: true),
30 | LastName = table.Column(type: "nvarchar(max)", nullable: true),
31 | UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
32 | NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
33 | Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
34 | NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true),
35 | EmailConfirmed = table.Column(type: "bit", nullable: false),
36 | PasswordHash = table.Column(type: "nvarchar(max)", nullable: true),
37 | SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true),
38 | ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true),
39 | PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true),
40 | PhoneNumberConfirmed = table.Column(type: "bit", nullable: false),
41 | TwoFactorEnabled = table.Column(type: "bit", nullable: false),
42 | LockoutEnd = table.Column(type: "datetimeoffset", nullable: true),
43 | LockoutEnabled = table.Column(type: "bit", nullable: false),
44 | AccessFailedCount = table.Column(type: "int", nullable: false)
45 | },
46 | constraints: table =>
47 | {
48 | table.PrimaryKey("PK_AspNetUsers", x => x.Id);
49 | });
50 |
51 | migrationBuilder.CreateTable(
52 | name: "IdentityUserLogin",
53 | columns: table => new
54 | {
55 | LoginProvider = table.Column(type: "nvarchar(max)", nullable: true),
56 | ProviderKey = table.Column(type: "nvarchar(max)", nullable: true),
57 | ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true),
58 | UserId = table.Column(type: "int", nullable: false)
59 | },
60 | constraints: table =>
61 | {
62 | });
63 |
64 | migrationBuilder.CreateTable(
65 | name: "AspNetRoleClaims",
66 | columns: table => new
67 | {
68 | Id = table.Column(type: "int", nullable: false)
69 | .Annotation("SqlServer:Identity", "1, 1"),
70 | RoleId = table.Column(type: "nvarchar(450)", nullable: false),
71 | ClaimType = table.Column(type: "nvarchar(max)", nullable: true),
72 | ClaimValue = table.Column(type: "nvarchar(max)", nullable: true)
73 | },
74 | constraints: table =>
75 | {
76 | table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
77 | table.ForeignKey(
78 | name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
79 | column: x => x.RoleId,
80 | principalTable: "AspNetRoles",
81 | principalColumn: "Id",
82 | onDelete: ReferentialAction.Cascade);
83 | });
84 |
85 | migrationBuilder.CreateTable(
86 | name: "AspNetUserClaims",
87 | columns: table => new
88 | {
89 | Id = table.Column(type: "int", nullable: false)
90 | .Annotation("SqlServer:Identity", "1, 1"),
91 | UserId = table.Column(type: "nvarchar(450)", nullable: false),
92 | ClaimType = table.Column(type: "nvarchar(max)", nullable: true),
93 | ClaimValue = table.Column(type: "nvarchar(max)", nullable: true)
94 | },
95 | constraints: table =>
96 | {
97 | table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
98 | table.ForeignKey(
99 | name: "FK_AspNetUserClaims_AspNetUsers_UserId",
100 | column: x => x.UserId,
101 | principalTable: "AspNetUsers",
102 | principalColumn: "Id",
103 | onDelete: ReferentialAction.Cascade);
104 | });
105 |
106 | migrationBuilder.CreateTable(
107 | name: "AspNetUserLogins",
108 | columns: table => new
109 | {
110 | LoginProvider = table.Column(type: "nvarchar(450)", nullable: false),
111 | ProviderKey = table.Column(type: "nvarchar(450)", nullable: false),
112 | ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true),
113 | UserId = table.Column(type: "nvarchar(450)", nullable: false)
114 | },
115 | constraints: table =>
116 | {
117 | table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
118 | table.ForeignKey(
119 | name: "FK_AspNetUserLogins_AspNetUsers_UserId",
120 | column: x => x.UserId,
121 | principalTable: "AspNetUsers",
122 | principalColumn: "Id",
123 | onDelete: ReferentialAction.Cascade);
124 | });
125 |
126 | migrationBuilder.CreateTable(
127 | name: "AspNetUserRoles",
128 | columns: table => new
129 | {
130 | UserId = table.Column(type: "nvarchar(450)", nullable: false),
131 | RoleId = table.Column(type: "nvarchar(450)", nullable: false)
132 | },
133 | constraints: table =>
134 | {
135 | table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
136 | table.ForeignKey(
137 | name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
138 | column: x => x.RoleId,
139 | principalTable: "AspNetRoles",
140 | principalColumn: "Id",
141 | onDelete: ReferentialAction.Cascade);
142 | table.ForeignKey(
143 | name: "FK_AspNetUserRoles_AspNetUsers_UserId",
144 | column: x => x.UserId,
145 | principalTable: "AspNetUsers",
146 | principalColumn: "Id",
147 | onDelete: ReferentialAction.Cascade);
148 | });
149 |
150 | migrationBuilder.CreateTable(
151 | name: "AspNetUserTokens",
152 | columns: table => new
153 | {
154 | UserId = table.Column(type: "nvarchar(450)", nullable: false),
155 | LoginProvider = table.Column(type: "nvarchar(450)", nullable: false),
156 | Name = table.Column(type: "nvarchar(450)", nullable: false),
157 | Value = table.Column(type: "nvarchar(max)", nullable: true)
158 | },
159 | constraints: table =>
160 | {
161 | table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
162 | table.ForeignKey(
163 | name: "FK_AspNetUserTokens_AspNetUsers_UserId",
164 | column: x => x.UserId,
165 | principalTable: "AspNetUsers",
166 | principalColumn: "Id",
167 | onDelete: ReferentialAction.Cascade);
168 | });
169 |
170 | migrationBuilder.CreateIndex(
171 | name: "IX_AspNetRoleClaims_RoleId",
172 | table: "AspNetRoleClaims",
173 | column: "RoleId");
174 |
175 | migrationBuilder.CreateIndex(
176 | name: "RoleNameIndex",
177 | table: "AspNetRoles",
178 | column: "NormalizedName",
179 | unique: true,
180 | filter: "[NormalizedName] IS NOT NULL");
181 |
182 | migrationBuilder.CreateIndex(
183 | name: "IX_AspNetUserClaims_UserId",
184 | table: "AspNetUserClaims",
185 | column: "UserId");
186 |
187 | migrationBuilder.CreateIndex(
188 | name: "IX_AspNetUserLogins_UserId",
189 | table: "AspNetUserLogins",
190 | column: "UserId");
191 |
192 | migrationBuilder.CreateIndex(
193 | name: "IX_AspNetUserRoles_RoleId",
194 | table: "AspNetUserRoles",
195 | column: "RoleId");
196 |
197 | migrationBuilder.CreateIndex(
198 | name: "EmailIndex",
199 | table: "AspNetUsers",
200 | column: "NormalizedEmail");
201 |
202 | migrationBuilder.CreateIndex(
203 | name: "UserNameIndex",
204 | table: "AspNetUsers",
205 | column: "NormalizedUserName",
206 | unique: true,
207 | filter: "[NormalizedUserName] IS NOT NULL");
208 | }
209 |
210 | protected override void Down(MigrationBuilder migrationBuilder)
211 | {
212 | migrationBuilder.DropTable(
213 | name: "AspNetRoleClaims");
214 |
215 | migrationBuilder.DropTable(
216 | name: "AspNetUserClaims");
217 |
218 | migrationBuilder.DropTable(
219 | name: "AspNetUserLogins");
220 |
221 | migrationBuilder.DropTable(
222 | name: "AspNetUserRoles");
223 |
224 | migrationBuilder.DropTable(
225 | name: "AspNetUserTokens");
226 |
227 | migrationBuilder.DropTable(
228 | name: "IdentityUserLogin");
229 |
230 | migrationBuilder.DropTable(
231 | name: "AspNetRoles");
232 |
233 | migrationBuilder.DropTable(
234 | name: "AspNetUsers");
235 | }
236 | }
237 | }
238 |
--------------------------------------------------------------------------------
/CompanyEmployee.API/Migrations/20210204062338_AddedRolesToDb.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using Entities;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Metadata;
7 | using Microsoft.EntityFrameworkCore.Migrations;
8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
9 |
10 | namespace CompanyEmployee.API.Migrations
11 | {
12 | [DbContext(typeof(CompanyEmployeeDbContext))]
13 | [Migration("20210204062338_AddedRolesToDb")]
14 | partial class AddedRolesToDb
15 | {
16 | protected override void BuildTargetModel(ModelBuilder modelBuilder)
17 | {
18 | #pragma warning disable 612, 618
19 | modelBuilder
20 | .UseIdentityColumns()
21 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
22 | .HasAnnotation("ProductVersion", "5.0.2");
23 |
24 | modelBuilder.Entity("Entities.Models.Company", b =>
25 | {
26 | b.Property("Id")
27 | .ValueGeneratedOnAdd()
28 | .HasColumnType("uniqueidentifier")
29 | .HasColumnName("CompanyId");
30 |
31 | b.Property("Address")
32 | .IsRequired()
33 | .HasMaxLength(60)
34 | .HasColumnType("nvarchar(60)");
35 |
36 | b.Property("Country")
37 | .HasColumnType("nvarchar(max)");
38 |
39 | b.Property("Name")
40 | .IsRequired()
41 | .HasMaxLength(60)
42 | .HasColumnType("nvarchar(60)");
43 |
44 | b.HasKey("Id");
45 |
46 | b.ToTable("Companies");
47 |
48 | b.HasData(
49 | new
50 | {
51 | Id = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
52 | Address = "Tehran,Tajrish",
53 | Country = "Iran",
54 | Name = "Raveshmand_Ltd"
55 | },
56 | new
57 | {
58 | Id = new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"),
59 | Address = "London",
60 | Country = "English",
61 | Name = "Geeks_Ltd"
62 | });
63 | });
64 |
65 | modelBuilder.Entity("Entities.Models.Employee", b =>
66 | {
67 | b.Property("Id")
68 | .ValueGeneratedOnAdd()
69 | .HasColumnType("uniqueidentifier")
70 | .HasColumnName("EmployeeId");
71 |
72 | b.Property("Age")
73 | .HasColumnType("int");
74 |
75 | b.Property("CompanyId")
76 | .HasColumnType("uniqueidentifier");
77 |
78 | b.Property("Name")
79 | .IsRequired()
80 | .HasMaxLength(30)
81 | .HasColumnType("nvarchar(30)");
82 |
83 | b.Property("Position")
84 | .IsRequired()
85 | .HasMaxLength(20)
86 | .HasColumnType("nvarchar(20)");
87 |
88 | b.HasKey("Id");
89 |
90 | b.HasIndex("CompanyId");
91 |
92 | b.ToTable("Employees");
93 |
94 | b.HasData(
95 | new
96 | {
97 | Id = new Guid("80abbca8-664d-4b20-b5de-024705497d4a"),
98 | Age = 26,
99 | CompanyId = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
100 | Name = "Zahra Bayat",
101 | Position = "Backend developer"
102 | },
103 | new
104 | {
105 | Id = new Guid("86dba8c0-d178-41e7-938c-ed49778fb52a"),
106 | Age = 30,
107 | CompanyId = new Guid("c9d4c053-49b6-410c-bc78-2d54a9991870"),
108 | Name = "Ali Bayat",
109 | Position = "Backend developer"
110 | },
111 | new
112 | {
113 | Id = new Guid("021ca3c1-0deb-4afd-ae94-2159a8479811"),
114 | Age = 35,
115 | CompanyId = new Guid("3d490a70-94ce-4d15-9494-5248280c2ce3"),
116 | Name = "Sara Bayat",
117 | Position = "Frontend developer"
118 | });
119 | });
120 |
121 | modelBuilder.Entity("Entities.Models.User", b =>
122 | {
123 | b.Property("Id")
124 | .HasColumnType("nvarchar(450)");
125 |
126 | b.Property("AccessFailedCount")
127 | .HasColumnType("int");
128 |
129 | b.Property("ConcurrencyStamp")
130 | .IsConcurrencyToken()
131 | .HasColumnType("nvarchar(max)");
132 |
133 | b.Property("Email")
134 | .HasMaxLength(256)
135 | .HasColumnType("nvarchar(256)");
136 |
137 | b.Property("EmailConfirmed")
138 | .HasColumnType("bit");
139 |
140 | b.Property("FirstName")
141 | .HasColumnType("nvarchar(max)");
142 |
143 | b.Property("LastName")
144 | .HasColumnType("nvarchar(max)");
145 |
146 | b.Property("LockoutEnabled")
147 | .HasColumnType("bit");
148 |
149 | b.Property("LockoutEnd")
150 | .HasColumnType("datetimeoffset");
151 |
152 | b.Property("NormalizedEmail")
153 | .HasMaxLength(256)
154 | .HasColumnType("nvarchar(256)");
155 |
156 | b.Property("NormalizedUserName")
157 | .HasMaxLength(256)
158 | .HasColumnType("nvarchar(256)");
159 |
160 | b.Property("PasswordHash")
161 | .HasColumnType("nvarchar(max)");
162 |
163 | b.Property("PhoneNumber")
164 | .HasColumnType("nvarchar(max)");
165 |
166 | b.Property("PhoneNumberConfirmed")
167 | .HasColumnType("bit");
168 |
169 | b.Property("SecurityStamp")
170 | .HasColumnType("nvarchar(max)");
171 |
172 | b.Property("TwoFactorEnabled")
173 | .HasColumnType("bit");
174 |
175 | b.Property("UserName")
176 | .HasMaxLength(256)
177 | .HasColumnType("nvarchar(256)");
178 |
179 | b.HasKey("Id");
180 |
181 | b.HasIndex("NormalizedEmail")
182 | .HasDatabaseName("EmailIndex");
183 |
184 | b.HasIndex("NormalizedUserName")
185 | .IsUnique()
186 | .HasDatabaseName("UserNameIndex")
187 | .HasFilter("[NormalizedUserName] IS NOT NULL");
188 |
189 | b.ToTable("AspNetUsers");
190 | });
191 |
192 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
193 | {
194 | b.Property("Id")
195 | .HasColumnType("nvarchar(450)");
196 |
197 | b.Property("ConcurrencyStamp")
198 | .IsConcurrencyToken()
199 | .HasColumnType("nvarchar(max)");
200 |
201 | b.Property("Name")
202 | .HasMaxLength(256)
203 | .HasColumnType("nvarchar(256)");
204 |
205 | b.Property("NormalizedName")
206 | .HasMaxLength(256)
207 | .HasColumnType("nvarchar(256)");
208 |
209 | b.HasKey("Id");
210 |
211 | b.HasIndex("NormalizedName")
212 | .IsUnique()
213 | .HasDatabaseName("RoleNameIndex")
214 | .HasFilter("[NormalizedName] IS NOT NULL");
215 |
216 | b.ToTable("AspNetRoles");
217 |
218 | b.HasData(
219 | new
220 | {
221 | Id = "c81c47b3-088e-4940-ab94-e0297e7a84fb",
222 | ConcurrencyStamp = "0d9a1a18-fb30-49ec-846f-fdb04f41c89a",
223 | Name = "Manager",
224 | NormalizedName = "MANAGER"
225 | },
226 | new
227 | {
228 | Id = "9d9e45fd-50e5-4016-860a-5d15e605b527",
229 | ConcurrencyStamp = "0ec324a1-dba2-4786-a9b6-38285b4a9b4c",
230 | Name = "Administrator",
231 | NormalizedName = "ADMINISTRATOR"
232 | });
233 | });
234 |
235 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
236 | {
237 | b.Property("Id")
238 | .ValueGeneratedOnAdd()
239 | .HasColumnType("int")
240 | .UseIdentityColumn();
241 |
242 | b.Property("ClaimType")
243 | .HasColumnType("nvarchar(max)");
244 |
245 | b.Property("ClaimValue")
246 | .HasColumnType("nvarchar(max)");
247 |
248 | b.Property("RoleId")
249 | .IsRequired()
250 | .HasColumnType("nvarchar(450)");
251 |
252 | b.HasKey("Id");
253 |
254 | b.HasIndex("RoleId");
255 |
256 | b.ToTable("AspNetRoleClaims");
257 | });
258 |
259 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
260 | {
261 | b.Property("Id")
262 | .ValueGeneratedOnAdd()
263 | .HasColumnType("int")
264 | .UseIdentityColumn();
265 |
266 | b.Property("ClaimType")
267 | .HasColumnType("nvarchar(max)");
268 |
269 | b.Property("ClaimValue")
270 | .HasColumnType("nvarchar(max)");
271 |
272 | b.Property("UserId")
273 | .IsRequired()
274 | .HasColumnType("nvarchar(450)");
275 |
276 | b.HasKey("Id");
277 |
278 | b.HasIndex("UserId");
279 |
280 | b.ToTable("AspNetUserClaims");
281 | });
282 |
283 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
284 | {
285 | b.Property("LoginProvider")
286 | .HasColumnType("nvarchar(max)");
287 |
288 | b.Property("ProviderDisplayName")
289 | .HasColumnType("nvarchar(max)");
290 |
291 | b.Property("ProviderKey")
292 | .HasColumnType("nvarchar(max)");
293 |
294 | b.Property("UserId")
295 | .HasColumnType("int");
296 |
297 | b.ToTable("IdentityUserLogin");
298 | });
299 |
300 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
301 | {
302 | b.Property("LoginProvider")
303 | .HasColumnType("nvarchar(450)");
304 |
305 | b.Property("ProviderKey")
306 | .HasColumnType("nvarchar(450)");
307 |
308 | b.Property("ProviderDisplayName")
309 | .HasColumnType("nvarchar(max)");
310 |
311 | b.Property("UserId")
312 | .IsRequired()
313 | .HasColumnType("nvarchar(450)");
314 |
315 | b.HasKey("LoginProvider", "ProviderKey");
316 |
317 | b.HasIndex("UserId");
318 |
319 | b.ToTable("AspNetUserLogins");
320 | });
321 |
322 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
323 | {
324 | b.Property("UserId")
325 | .HasColumnType("nvarchar(450)");
326 |
327 | b.Property("RoleId")
328 | .HasColumnType("nvarchar(450)");
329 |
330 | b.HasKey("UserId", "RoleId");
331 |
332 | b.HasIndex("RoleId");
333 |
334 | b.ToTable("AspNetUserRoles");
335 | });
336 |
337 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
338 | {
339 | b.Property("UserId")
340 | .HasColumnType("nvarchar(450)");
341 |
342 | b.Property