├── .gitignore ├── Module 2 - Hello World ├── MoviesAPI.sln └── MoviesAPI │ ├── Controllers │ └── WeatherForecastController.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Module 3 - Fundamentals of ASP.NET Core ├── End │ ├── MoviesAPI.sln │ └── MoviesAPI │ │ ├── Controllers │ │ ├── GenresController.cs │ │ └── WeatherForecastController.cs │ │ ├── Entities │ │ └── Genre.cs │ │ ├── Filters │ │ ├── MyActionFilter.cs │ │ └── MyExceptionFilter.cs │ │ ├── MoviesAPI.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── IRepository.cs │ │ ├── InMemoryRepository.cs │ │ └── WriteToFileHostedService.cs │ │ ├── Startup.cs │ │ ├── Validations │ │ └── FirstLetterUppercaseAttribute.cs │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ └── File 1.txt └── Start │ ├── MoviesAPI.sln │ └── MoviesAPI │ ├── Controllers │ └── WeatherForecastController.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Module 4 - Resource Manipulation and Entity Framework Core ├── End │ ├── MoviesAPI.sln │ └── MoviesAPI │ │ ├── ApplicationDbContext.cs │ │ ├── Controllers │ │ ├── GenresController.cs │ │ ├── MoviesController.cs │ │ └── PeopleController.cs │ │ ├── DTOs │ │ ├── ActorCreationDTO.cs │ │ ├── ActorDTO.cs │ │ ├── FilterMoviesDTO.cs │ │ ├── GenreCreationDTO.cs │ │ ├── GenreDTO.cs │ │ ├── IndexMoviePageDTO.cs │ │ ├── MovieCreationDTO.cs │ │ ├── MovieDTO.cs │ │ ├── MovieDetailsDTO.cs │ │ ├── MoviePatchDTO.cs │ │ ├── PaginationDTO.cs │ │ ├── PersonCreationDTO.cs │ │ ├── PersonDTO.cs │ │ └── PersonPatchDTO.cs │ │ ├── Entities │ │ ├── Genre.cs │ │ ├── Movie.cs │ │ ├── MoviesActors.cs │ │ ├── MoviesGenres.cs │ │ └── Person.cs │ │ ├── Filters │ │ └── MyExceptionFilter.cs │ │ ├── Helpers │ │ ├── AutoMapperProfiles.cs │ │ ├── HttpContextExtensions.cs │ │ ├── QueryableExtensions.cs │ │ └── TypeBinder.cs │ │ ├── Migrations │ │ ├── 20200210001057_Initial.Designer.cs │ │ ├── 20200210001057_Initial.cs │ │ ├── 20200210174840_Person.Designer.cs │ │ ├── 20200210174840_Person.cs │ │ ├── 20200212194055_Movie.Designer.cs │ │ ├── 20200212194055_Movie.cs │ │ ├── 20200213025354_ManyToMany.Designer.cs │ │ ├── 20200213025354_ManyToMany.cs │ │ ├── 20200214015103_TestData.Designer.cs │ │ ├── 20200214015103_TestData.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ │ ├── MoviesAPI.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── AzureStorageService.cs │ │ ├── IFileStorageService.cs │ │ ├── InAppStorageService.cs │ │ ├── MovieInTheatersService.cs │ │ └── WriteToFileHostedService.cs │ │ ├── Startup.cs │ │ ├── Validations │ │ ├── ContentTypeValidator.cs │ │ ├── FileSizeValidator.cs │ │ └── FirstLetterUppercaseAttribute.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ └── people │ │ └── c173b2ce-8162-42fe-a390-de3bb6d4f48f.jpg └── Start │ ├── MoviesAPI.sln │ └── MoviesAPI │ ├── Controllers │ ├── GenresController.cs │ └── WeatherForecastController.cs │ ├── Entities │ └── Genre.cs │ ├── Filters │ ├── MyActionFilter.cs │ └── MyExceptionFilter.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ ├── IRepository.cs │ ├── InMemoryRepository.cs │ └── WriteToFileHostedService.cs │ ├── Startup.cs │ ├── Validations │ └── FirstLetterUppercaseAttribute.cs │ ├── WeatherForecast.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Module 5 - Configurations ├── End │ ├── MoviesAPI.sln │ └── MoviesAPI │ │ ├── ApplicationDbContext.cs │ │ ├── Controllers │ │ ├── ConfigurationController.cs │ │ ├── GenresController.cs │ │ ├── MoviesController.cs │ │ └── PeopleController.cs │ │ ├── DTOs │ │ ├── ActorCreationDTO.cs │ │ ├── ActorDTO.cs │ │ ├── FilterMoviesDTO.cs │ │ ├── GenreCreationDTO.cs │ │ ├── GenreDTO.cs │ │ ├── IndexMoviePageDTO.cs │ │ ├── MovieCreationDTO.cs │ │ ├── MovieDTO.cs │ │ ├── MovieDetailsDTO.cs │ │ ├── MoviePatchDTO.cs │ │ ├── PaginationDTO.cs │ │ ├── PersonCreationDTO.cs │ │ ├── PersonDTO.cs │ │ └── PersonPatchDTO.cs │ │ ├── Entities │ │ ├── Genre.cs │ │ ├── Movie.cs │ │ ├── MoviesActors.cs │ │ ├── MoviesGenres.cs │ │ └── Person.cs │ │ ├── Filters │ │ └── MyExceptionFilter.cs │ │ ├── Helpers │ │ ├── AutoMapperProfiles.cs │ │ ├── HttpContextExtensions.cs │ │ ├── QueryableExtensions.cs │ │ └── TypeBinder.cs │ │ ├── Migrations │ │ ├── 20200210001057_Initial.Designer.cs │ │ ├── 20200210001057_Initial.cs │ │ ├── 20200210174840_Person.Designer.cs │ │ ├── 20200210174840_Person.cs │ │ ├── 20200212194055_Movie.Designer.cs │ │ ├── 20200212194055_Movie.cs │ │ ├── 20200213025354_ManyToMany.Designer.cs │ │ ├── 20200213025354_ManyToMany.cs │ │ ├── 20200214015103_TestData.Designer.cs │ │ ├── 20200214015103_TestData.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ │ ├── MoviesAPI.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── AzureStorageService.cs │ │ ├── IFileStorageService.cs │ │ ├── InAppStorageService.cs │ │ ├── MovieInTheatersService.cs │ │ └── WriteToFileHostedService.cs │ │ ├── Startup.cs │ │ ├── Validations │ │ ├── ContentTypeValidator.cs │ │ ├── FileSizeValidator.cs │ │ └── FirstLetterUppercaseAttribute.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json └── Start │ ├── MoviesAPI.sln │ └── MoviesAPI │ ├── ApplicationDbContext.cs │ ├── Controllers │ ├── GenresController.cs │ ├── MoviesController.cs │ └── PeopleController.cs │ ├── DTOs │ ├── ActorCreationDTO.cs │ ├── ActorDTO.cs │ ├── FilterMoviesDTO.cs │ ├── GenreCreationDTO.cs │ ├── GenreDTO.cs │ ├── IndexMoviePageDTO.cs │ ├── MovieCreationDTO.cs │ ├── MovieDTO.cs │ ├── MovieDetailsDTO.cs │ ├── MoviePatchDTO.cs │ ├── PaginationDTO.cs │ ├── PersonCreationDTO.cs │ ├── PersonDTO.cs │ └── PersonPatchDTO.cs │ ├── Entities │ ├── Genre.cs │ ├── Movie.cs │ ├── MoviesActors.cs │ ├── MoviesGenres.cs │ └── Person.cs │ ├── Filters │ └── MyExceptionFilter.cs │ ├── Helpers │ ├── AutoMapperProfiles.cs │ ├── HttpContextExtensions.cs │ ├── QueryableExtensions.cs │ └── TypeBinder.cs │ ├── Migrations │ ├── 20200210001057_Initial.Designer.cs │ ├── 20200210001057_Initial.cs │ ├── 20200210174840_Person.Designer.cs │ ├── 20200210174840_Person.cs │ ├── 20200212194055_Movie.Designer.cs │ ├── 20200212194055_Movie.cs │ ├── 20200213025354_ManyToMany.Designer.cs │ ├── 20200213025354_ManyToMany.cs │ ├── 20200214015103_TestData.Designer.cs │ ├── 20200214015103_TestData.cs │ └── ApplicationDbContextModelSnapshot.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ ├── AzureStorageService.cs │ ├── IFileStorageService.cs │ ├── InAppStorageService.cs │ ├── MovieInTheatersService.cs │ └── WriteToFileHostedService.cs │ ├── Startup.cs │ ├── Validations │ ├── ContentTypeValidator.cs │ ├── FileSizeValidator.cs │ └── FirstLetterUppercaseAttribute.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Module 6 - Security ├── End │ ├── MoviesAPI.sln │ └── MoviesAPI │ │ ├── ApplicationDbContext.cs │ │ ├── Controllers │ │ ├── AccountsController.cs │ │ ├── GenresController.cs │ │ ├── MoviesController.cs │ │ ├── PeopleController.cs │ │ └── SecurityController.cs │ │ ├── DTOs │ │ ├── ActorCreationDTO.cs │ │ ├── ActorDTO.cs │ │ ├── EditRoleDTO.cs │ │ ├── FilterMoviesDTO.cs │ │ ├── GenreCreationDTO.cs │ │ ├── GenreDTO.cs │ │ ├── HashResult.cs │ │ ├── IndexMoviePageDTO.cs │ │ ├── MovieCreationDTO.cs │ │ ├── MovieDTO.cs │ │ ├── MovieDetailsDTO.cs │ │ ├── MoviePatchDTO.cs │ │ ├── PaginationDTO.cs │ │ ├── PersonCreationDTO.cs │ │ ├── PersonDTO.cs │ │ ├── PersonPatchDTO.cs │ │ ├── UserDTO.cs │ │ ├── UserInfo.cs │ │ └── UserToken.cs │ │ ├── Entities │ │ ├── Genre.cs │ │ ├── Movie.cs │ │ ├── MoviesActors.cs │ │ ├── MoviesGenres.cs │ │ └── Person.cs │ │ ├── Filters │ │ └── MyExceptionFilter.cs │ │ ├── Helpers │ │ ├── AutoMapperProfiles.cs │ │ ├── HttpContextExtensions.cs │ │ ├── QueryableExtensions.cs │ │ └── TypeBinder.cs │ │ ├── Migrations │ │ ├── 20200210001057_Initial.Designer.cs │ │ ├── 20200210001057_Initial.cs │ │ ├── 20200210174840_Person.Designer.cs │ │ ├── 20200210174840_Person.cs │ │ ├── 20200212194055_Movie.Designer.cs │ │ ├── 20200212194055_Movie.cs │ │ ├── 20200213025354_ManyToMany.Designer.cs │ │ ├── 20200213025354_ManyToMany.cs │ │ ├── 20200214015103_TestData.Designer.cs │ │ ├── 20200214015103_TestData.cs │ │ ├── 20200226191708_IdentityTables.Designer.cs │ │ ├── 20200226191708_IdentityTables.cs │ │ ├── 20200227021523_AdminRole.Designer.cs │ │ ├── 20200227021523_AdminRole.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ │ ├── MoviesAPI.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── AzureStorageService.cs │ │ ├── HashService.cs │ │ ├── IFileStorageService.cs │ │ ├── InAppStorageService.cs │ │ ├── MovieInTheatersService.cs │ │ └── WriteToFileHostedService.cs │ │ ├── Startup.cs │ │ ├── Validations │ │ ├── ContentTypeValidator.cs │ │ ├── FileSizeValidator.cs │ │ └── FirstLetterUppercaseAttribute.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json └── Start │ ├── MoviesAPI.sln │ └── MoviesAPI │ ├── ApplicationDbContext.cs │ ├── Controllers │ ├── GenresController.cs │ ├── MoviesController.cs │ └── PeopleController.cs │ ├── DTOs │ ├── ActorCreationDTO.cs │ ├── ActorDTO.cs │ ├── FilterMoviesDTO.cs │ ├── GenreCreationDTO.cs │ ├── GenreDTO.cs │ ├── IndexMoviePageDTO.cs │ ├── MovieCreationDTO.cs │ ├── MovieDTO.cs │ ├── MovieDetailsDTO.cs │ ├── MoviePatchDTO.cs │ ├── PaginationDTO.cs │ ├── PersonCreationDTO.cs │ ├── PersonDTO.cs │ └── PersonPatchDTO.cs │ ├── Entities │ ├── Genre.cs │ ├── Movie.cs │ ├── MoviesActors.cs │ ├── MoviesGenres.cs │ └── Person.cs │ ├── Filters │ └── MyExceptionFilter.cs │ ├── Helpers │ ├── AutoMapperProfiles.cs │ ├── HttpContextExtensions.cs │ ├── QueryableExtensions.cs │ └── TypeBinder.cs │ ├── Migrations │ ├── 20200210001057_Initial.Designer.cs │ ├── 20200210001057_Initial.cs │ ├── 20200210174840_Person.Designer.cs │ ├── 20200210174840_Person.cs │ ├── 20200212194055_Movie.Designer.cs │ ├── 20200212194055_Movie.cs │ ├── 20200213025354_ManyToMany.Designer.cs │ ├── 20200213025354_ManyToMany.cs │ ├── 20200214015103_TestData.Designer.cs │ ├── 20200214015103_TestData.cs │ └── ApplicationDbContextModelSnapshot.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ ├── AzureStorageService.cs │ ├── IFileStorageService.cs │ ├── InAppStorageService.cs │ ├── MovieInTheatersService.cs │ └── WriteToFileHostedService.cs │ ├── Startup.cs │ ├── Validations │ ├── ContentTypeValidator.cs │ ├── FileSizeValidator.cs │ └── FirstLetterUppercaseAttribute.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Module 7 - Advanced Scenarios ├── End │ ├── MoviesAPI.sln │ └── MoviesAPI │ │ ├── ApplicationDbContext.cs │ │ ├── Controllers │ │ ├── AccountsController.cs │ │ ├── CustomBaseController.cs │ │ ├── DefaultController.cs │ │ ├── GenresController.cs │ │ ├── MovieTheatersController.cs │ │ ├── MoviesController.cs │ │ ├── PeopleController.cs │ │ ├── RootController.cs │ │ └── V2 │ │ │ └── RootController.cs │ │ ├── DTOs │ │ ├── ActorCreationDTO.cs │ │ ├── ActorDTO.cs │ │ ├── EditRoleDTO.cs │ │ ├── FilterMovieTheatersDTO.cs │ │ ├── FilterMoviesDTO.cs │ │ ├── GenreCreationDTO.cs │ │ ├── GenreDTO.cs │ │ ├── HashResult.cs │ │ ├── IGenerateHATEOASLinks.cs │ │ ├── IndexMoviePageDTO.cs │ │ ├── Link.cs │ │ ├── MovieCreationDTO.cs │ │ ├── MovieDTO.cs │ │ ├── MovieDetailsDTO.cs │ │ ├── MoviePatchDTO.cs │ │ ├── MovieTheatherDTO.cs │ │ ├── PaginationDTO.cs │ │ ├── PersonCreationDTO.cs │ │ ├── PersonDTO.cs │ │ ├── PersonPatchDTO.cs │ │ ├── ResourceCollection.cs │ │ ├── UserDTO.cs │ │ ├── UserInfo.cs │ │ └── UserToken.cs │ │ ├── Entities │ │ ├── Genre.cs │ │ ├── IId.cs │ │ ├── Movie.cs │ │ ├── MovieTheater.cs │ │ ├── MoviesActors.cs │ │ ├── MoviesGenres.cs │ │ └── Person.cs │ │ ├── Filters │ │ └── MyExceptionFilter.cs │ │ ├── Helpers │ │ ├── AutoMapperProfiles.cs │ │ ├── GenreHATEOASAttribute.cs │ │ ├── HATEOASAttribute.cs │ │ ├── HttpContextExtensions.cs │ │ ├── HttpHeaderIsPresentAttribute.cs │ │ ├── QueryableExtensions.cs │ │ └── TypeBinder.cs │ │ ├── Migrations │ │ ├── 20200210001057_Initial.Designer.cs │ │ ├── 20200210001057_Initial.cs │ │ ├── 20200210174840_Person.Designer.cs │ │ ├── 20200210174840_Person.cs │ │ ├── 20200212194055_Movie.Designer.cs │ │ ├── 20200212194055_Movie.cs │ │ ├── 20200213025354_ManyToMany.Designer.cs │ │ ├── 20200213025354_ManyToMany.cs │ │ ├── 20200214015103_TestData.Designer.cs │ │ ├── 20200214015103_TestData.cs │ │ ├── 20200226191708_IdentityTables.Designer.cs │ │ ├── 20200226191708_IdentityTables.cs │ │ ├── 20200227021523_AdminRole.Designer.cs │ │ ├── 20200227021523_AdminRole.cs │ │ ├── 20200303203224_MovieTheaterEntity.Designer.cs │ │ ├── 20200303203224_MovieTheaterEntity.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ │ ├── MoviesAPI.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── AzureStorageService.cs │ │ ├── IFileStorageService.cs │ │ ├── InAppStorageService.cs │ │ ├── LinksGenerator.cs │ │ ├── MovieInTheatersService.cs │ │ └── WriteToFileHostedService.cs │ │ ├── Startup.cs │ │ ├── Validations │ │ ├── ContentTypeValidator.cs │ │ ├── FileSizeValidator.cs │ │ └── FirstLetterUppercaseAttribute.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json └── Start │ ├── MoviesAPI.sln │ └── MoviesAPI │ ├── ApplicationDbContext.cs │ ├── Controllers │ ├── AccountsController.cs │ ├── GenresController.cs │ ├── MoviesController.cs │ └── PeopleController.cs │ ├── DTOs │ ├── ActorCreationDTO.cs │ ├── ActorDTO.cs │ ├── EditRoleDTO.cs │ ├── FilterMoviesDTO.cs │ ├── GenreCreationDTO.cs │ ├── GenreDTO.cs │ ├── HashResult.cs │ ├── IndexMoviePageDTO.cs │ ├── MovieCreationDTO.cs │ ├── MovieDTO.cs │ ├── MovieDetailsDTO.cs │ ├── MoviePatchDTO.cs │ ├── PaginationDTO.cs │ ├── PersonCreationDTO.cs │ ├── PersonDTO.cs │ ├── PersonPatchDTO.cs │ ├── UserDTO.cs │ ├── UserInfo.cs │ └── UserToken.cs │ ├── Entities │ ├── Genre.cs │ ├── Movie.cs │ ├── MoviesActors.cs │ ├── MoviesGenres.cs │ └── Person.cs │ ├── Filters │ └── MyExceptionFilter.cs │ ├── Helpers │ ├── AutoMapperProfiles.cs │ ├── HttpContextExtensions.cs │ ├── QueryableExtensions.cs │ └── TypeBinder.cs │ ├── Migrations │ ├── 20200210001057_Initial.Designer.cs │ ├── 20200210001057_Initial.cs │ ├── 20200210174840_Person.Designer.cs │ ├── 20200210174840_Person.cs │ ├── 20200212194055_Movie.Designer.cs │ ├── 20200212194055_Movie.cs │ ├── 20200213025354_ManyToMany.Designer.cs │ ├── 20200213025354_ManyToMany.cs │ ├── 20200214015103_TestData.Designer.cs │ ├── 20200214015103_TestData.cs │ ├── 20200226191708_IdentityTables.Designer.cs │ ├── 20200226191708_IdentityTables.cs │ ├── 20200227021523_AdminRole.Designer.cs │ ├── 20200227021523_AdminRole.cs │ └── ApplicationDbContextModelSnapshot.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ ├── AzureStorageService.cs │ ├── IFileStorageService.cs │ ├── InAppStorageService.cs │ ├── MovieInTheatersService.cs │ └── WriteToFileHostedService.cs │ ├── Startup.cs │ ├── Validations │ ├── ContentTypeValidator.cs │ ├── FileSizeValidator.cs │ └── FirstLetterUppercaseAttribute.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Module 8 - Testing ├── End │ ├── MoviesAPI.Tests │ │ ├── AllowAnonymousHandler.cs │ │ ├── BaseTests.cs │ │ ├── FakeUserFilter.cs │ │ ├── IntegrationTests │ │ │ └── GenresControllerTests.cs │ │ ├── LocalDbDatabaseInitializer.cs │ │ ├── MoviesAPI.Tests.csproj │ │ ├── Properties │ │ │ └── launchSettings.json │ │ └── UnitTests │ │ │ ├── AccountsControllerTests.cs │ │ │ ├── GenresControllerTests.cs │ │ │ ├── MovieTheatersControllerTests.cs │ │ │ ├── MoviesControllerTests.cs │ │ │ ├── PeopleControllerTests.cs │ │ │ ├── TransferServiceTests.cs │ │ │ └── WireTransferValidatorTests.cs │ ├── MoviesAPI.sln │ └── MoviesAPI │ │ ├── ApplicationDbContext.cs │ │ ├── Controllers │ │ ├── AccountsController.cs │ │ ├── CustomBaseController.cs │ │ ├── DefaultController.cs │ │ ├── GenresController.cs │ │ ├── MovieTheatersController.cs │ │ ├── MoviesController.cs │ │ ├── PeopleController.cs │ │ └── RootController.cs │ │ ├── DTOs │ │ ├── ActorCreationDTO.cs │ │ ├── ActorDTO.cs │ │ ├── EditRoleDTO.cs │ │ ├── FilterMovieTheatersDTO.cs │ │ ├── FilterMoviesDTO.cs │ │ ├── GenreCreationDTO.cs │ │ ├── GenreDTO.cs │ │ ├── HashResult.cs │ │ ├── IGenerateHATEOASLinks.cs │ │ ├── IndexMoviePageDTO.cs │ │ ├── Link.cs │ │ ├── MovieCreationDTO.cs │ │ ├── MovieDTO.cs │ │ ├── MovieDetailsDTO.cs │ │ ├── MoviePatchDTO.cs │ │ ├── MovieTheatherDTO.cs │ │ ├── PaginationDTO.cs │ │ ├── PersonCreationDTO.cs │ │ ├── PersonDTO.cs │ │ ├── PersonPatchDTO.cs │ │ ├── ResourceCollection.cs │ │ ├── UserDTO.cs │ │ ├── UserInfo.cs │ │ └── UserToken.cs │ │ ├── Entities │ │ ├── Genre.cs │ │ ├── IId.cs │ │ ├── Movie.cs │ │ ├── MovieTheater.cs │ │ ├── MoviesActors.cs │ │ ├── MoviesGenres.cs │ │ └── Person.cs │ │ ├── Filters │ │ └── MyExceptionFilter.cs │ │ ├── Helpers │ │ ├── AutoMapperProfiles.cs │ │ ├── GenreHATEOASAttribute.cs │ │ ├── HATEOASAttribute.cs │ │ ├── HttpContextExtensions.cs │ │ ├── HttpHeaderIsPresentAttribute.cs │ │ ├── QueryableExtensions.cs │ │ └── TypeBinder.cs │ │ ├── Migrations │ │ ├── 20200210001057_Initial.Designer.cs │ │ ├── 20200210001057_Initial.cs │ │ ├── 20200210174840_Person.Designer.cs │ │ ├── 20200210174840_Person.cs │ │ ├── 20200212194055_Movie.Designer.cs │ │ ├── 20200212194055_Movie.cs │ │ ├── 20200213025354_ManyToMany.Designer.cs │ │ ├── 20200213025354_ManyToMany.cs │ │ ├── 20200214015103_TestData.Designer.cs │ │ ├── 20200214015103_TestData.cs │ │ ├── 20200226191708_IdentityTables.Designer.cs │ │ ├── 20200226191708_IdentityTables.cs │ │ ├── 20200227021523_AdminRole.Designer.cs │ │ ├── 20200227021523_AdminRole.cs │ │ ├── 20200303203224_MovieTheaterEntity.Designer.cs │ │ ├── 20200303203224_MovieTheaterEntity.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ │ ├── MoviesAPI.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Services │ │ ├── AzureStorageService.cs │ │ ├── IFileStorageService.cs │ │ ├── InAppStorageService.cs │ │ ├── LinksGenerator.cs │ │ ├── MovieInTheatersService.cs │ │ └── WriteToFileHostedService.cs │ │ ├── Startup.cs │ │ ├── Testing │ │ ├── Account.cs │ │ ├── IValidateWireTransfer.cs │ │ ├── OperationResult.cs │ │ ├── TransferService.cs │ │ └── WireTransferValidator.cs │ │ ├── Validations │ │ ├── ContentTypeValidator.cs │ │ ├── FileSizeValidator.cs │ │ └── FirstLetterUppercaseAttribute.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json └── Start │ ├── MoviesAPI.sln │ └── MoviesAPI │ ├── ApplicationDbContext.cs │ ├── Controllers │ ├── AccountsController.cs │ ├── CustomBaseController.cs │ ├── DefaultController.cs │ ├── GenresController.cs │ ├── MovieTheatersController.cs │ ├── MoviesController.cs │ ├── PeopleController.cs │ └── RootController.cs │ ├── DTOs │ ├── ActorCreationDTO.cs │ ├── ActorDTO.cs │ ├── EditRoleDTO.cs │ ├── FilterMovieTheatersDTO.cs │ ├── FilterMoviesDTO.cs │ ├── GenreCreationDTO.cs │ ├── GenreDTO.cs │ ├── HashResult.cs │ ├── IGenerateHATEOASLinks.cs │ ├── IndexMoviePageDTO.cs │ ├── Link.cs │ ├── MovieCreationDTO.cs │ ├── MovieDTO.cs │ ├── MovieDetailsDTO.cs │ ├── MoviePatchDTO.cs │ ├── MovieTheatherDTO.cs │ ├── PaginationDTO.cs │ ├── PersonCreationDTO.cs │ ├── PersonDTO.cs │ ├── PersonPatchDTO.cs │ ├── ResourceCollection.cs │ ├── UserDTO.cs │ ├── UserInfo.cs │ └── UserToken.cs │ ├── Entities │ ├── Genre.cs │ ├── IId.cs │ ├── Movie.cs │ ├── MovieTheater.cs │ ├── MoviesActors.cs │ ├── MoviesGenres.cs │ └── Person.cs │ ├── Filters │ └── MyExceptionFilter.cs │ ├── Helpers │ ├── AutoMapperProfiles.cs │ ├── GenreHATEOASAttribute.cs │ ├── HATEOASAttribute.cs │ ├── HttpContextExtensions.cs │ ├── HttpHeaderIsPresentAttribute.cs │ ├── QueryableExtensions.cs │ └── TypeBinder.cs │ ├── Migrations │ ├── 20200210001057_Initial.Designer.cs │ ├── 20200210001057_Initial.cs │ ├── 20200210174840_Person.Designer.cs │ ├── 20200210174840_Person.cs │ ├── 20200212194055_Movie.Designer.cs │ ├── 20200212194055_Movie.cs │ ├── 20200213025354_ManyToMany.Designer.cs │ ├── 20200213025354_ManyToMany.cs │ ├── 20200214015103_TestData.Designer.cs │ ├── 20200214015103_TestData.cs │ ├── 20200226191708_IdentityTables.Designer.cs │ ├── 20200226191708_IdentityTables.cs │ ├── 20200227021523_AdminRole.Designer.cs │ ├── 20200227021523_AdminRole.cs │ ├── 20200303203224_MovieTheaterEntity.Designer.cs │ ├── 20200303203224_MovieTheaterEntity.cs │ └── ApplicationDbContextModelSnapshot.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Services │ ├── AzureStorageService.cs │ ├── IFileStorageService.cs │ ├── InAppStorageService.cs │ ├── LinksGenerator.cs │ ├── MovieInTheatersService.cs │ └── WriteToFileHostedService.cs │ ├── Startup.cs │ ├── Validations │ ├── ContentTypeValidator.cs │ ├── FileSizeValidator.cs │ └── FirstLetterUppercaseAttribute.cs │ ├── appsettings.Development.json │ └── appsettings.json ├── Module 9 - Deployment └── AzureAppService │ ├── MoviesAPI.Tests │ ├── AllowAnonymousHandler.cs │ ├── BaseTests.cs │ ├── FakeUserFilter.cs │ ├── IntegrationTests │ │ └── GenresControllerTests.cs │ ├── LocalDbDatabaseInitializer.cs │ ├── MoviesAPI.Tests.csproj │ ├── Properties │ │ └── launchSettings.json │ └── UnitTests │ │ ├── AccountsControllerTests.cs │ │ ├── GenresControllerTests.cs │ │ ├── MovieTheatersControllerTests.cs │ │ ├── MoviesControllerTests.cs │ │ └── PeopleControllerTests.cs │ ├── MoviesAPI.sln │ ├── MoviesAPI │ ├── ApplicationDbContext.cs │ ├── Controllers │ │ ├── AccountsController.cs │ │ ├── CustomBaseController.cs │ │ ├── DefaultController.cs │ │ ├── GenresController.cs │ │ ├── MovieTheatersController.cs │ │ ├── MoviesController.cs │ │ ├── PeopleController.cs │ │ └── RootController.cs │ ├── DTOs │ │ ├── ActorCreationDTO.cs │ │ ├── ActorDTO.cs │ │ ├── EditRoleDTO.cs │ │ ├── FilterMovieTheatersDTO.cs │ │ ├── FilterMoviesDTO.cs │ │ ├── GenreCreationDTO.cs │ │ ├── GenreDTO.cs │ │ ├── HashResult.cs │ │ ├── IGenerateHATEOASLinks.cs │ │ ├── IndexMoviePageDTO.cs │ │ ├── Link.cs │ │ ├── MovieCreationDTO.cs │ │ ├── MovieDTO.cs │ │ ├── MovieDetailsDTO.cs │ │ ├── MoviePatchDTO.cs │ │ ├── MovieTheatherDTO.cs │ │ ├── PaginationDTO.cs │ │ ├── PersonCreationDTO.cs │ │ ├── PersonDTO.cs │ │ ├── PersonPatchDTO.cs │ │ ├── ResourceCollection.cs │ │ ├── UserDTO.cs │ │ ├── UserInfo.cs │ │ └── UserToken.cs │ ├── Entities │ │ ├── Genre.cs │ │ ├── IId.cs │ │ ├── Movie.cs │ │ ├── MovieTheater.cs │ │ ├── MoviesActors.cs │ │ ├── MoviesGenres.cs │ │ └── Person.cs │ ├── Filters │ │ └── MyExceptionFilter.cs │ ├── Helpers │ │ ├── AutoMapperProfiles.cs │ │ ├── GenreHATEOASAttribute.cs │ │ ├── HATEOASAttribute.cs │ │ ├── HealthCheckResponseWriter.cs │ │ ├── HttpContextExtensions.cs │ │ ├── HttpHeaderIsPresentAttribute.cs │ │ ├── QueryableExtensions.cs │ │ └── TypeBinder.cs │ ├── Migrations │ │ ├── 20200210001057_Initial.Designer.cs │ │ ├── 20200210001057_Initial.cs │ │ ├── 20200210174840_Person.Designer.cs │ │ ├── 20200210174840_Person.cs │ │ ├── 20200212194055_Movie.Designer.cs │ │ ├── 20200212194055_Movie.cs │ │ ├── 20200213025354_ManyToMany.Designer.cs │ │ ├── 20200213025354_ManyToMany.cs │ │ ├── 20200214015103_TestData.Designer.cs │ │ ├── 20200214015103_TestData.cs │ │ ├── 20200226191708_IdentityTables.Designer.cs │ │ ├── 20200226191708_IdentityTables.cs │ │ ├── 20200227021523_AdminRole.Designer.cs │ │ ├── 20200227021523_AdminRole.cs │ │ ├── 20200303203224_MovieTheaterEntity.Designer.cs │ │ ├── 20200303203224_MovieTheaterEntity.cs │ │ ├── 20200312020120_AdminUser.Designer.cs │ │ ├── 20200312020120_AdminUser.cs │ │ ├── 20200313024102_Temp1.Designer.cs │ │ ├── 20200313024102_Temp1.cs │ │ └── ApplicationDbContextModelSnapshot.cs │ ├── MoviesAPI.csproj │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Services │ │ ├── AzureStorageService.cs │ │ ├── IFileStorageService.cs │ │ ├── InAppStorageService.cs │ │ ├── LinksGenerator.cs │ │ ├── MovieInTheatersService.cs │ │ └── WriteToFileHostedService.cs │ ├── Startup.cs │ ├── Validations │ │ ├── ContentTypeValidator.cs │ │ ├── FileSizeValidator.cs │ │ └── FirstLetterUppercaseAttribute.cs │ ├── appsettings.Development.json │ └── appsettings.json │ ├── azure-pipelines.yml │ └── migrations.sql └── README.md /Module 2 - Hello World/MoviesAPI/MoviesAPI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Module 2 - Hello World/MoviesAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace MoviesAPI 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 2 - Hello World/MoviesAPI/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MoviesAPI 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 2 - Hello World/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Module 2 - Hello World/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/End/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/End/MoviesAPI/MoviesAPI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/End/MoviesAPI/Services/IRepository.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Services 8 | { 9 | public interface IRepository 10 | { 11 | void AddGenre(Genre genre); 12 | Task> GetAllGenres(); 13 | Genre GetGenreById(int Id); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/End/MoviesAPI/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MoviesAPI 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/End/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/End/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/Start/MoviesAPI/MoviesAPI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/Start/MoviesAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace MoviesAPI 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/Start/MoviesAPI/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MoviesAPI 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/Start/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Module 3 - Fundamentals of ASP.NET Core/Start/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/GenreDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class GenreDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/wwwroot/people/c173b2ce-8162-42fe-a390-de3bb6d4f48f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavilanch/MoviesAPI/b6cd704ede774f0c32e6f56cd1c757eab5029072/Module 4 - Resource Manipulation and Entity Framework Core/End/MoviesAPI/wwwroot/people/c173b2ce-8162-42fe-a390-de3bb6d4f48f.jpg -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/Start/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/Start/MoviesAPI/MoviesAPI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/Start/MoviesAPI/Services/IRepository.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Services 8 | { 9 | public interface IRepository 10 | { 11 | void AddGenre(Genre genre); 12 | Task> GetAllGenres(); 13 | Genre GetGenreById(int Id); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/Start/MoviesAPI/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MoviesAPI 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/Start/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 4 - Resource Manipulation and Entity Framework Core/Start/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Controllers/ConfigurationController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Configuration; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Controllers 9 | { 10 | [ApiController] 11 | [Route("api/configuration")] 12 | public class ConfigurationController: ControllerBase 13 | { 14 | private readonly IConfiguration configuration; 15 | 16 | public ConfigurationController(IConfiguration configuration) 17 | { 18 | this.configuration = configuration; 19 | } 20 | 21 | [HttpGet] 22 | public IActionResult Get() 23 | { 24 | return Ok(configuration["lastname"]); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/GenreDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class GenreDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using MoviesAPI.Controllers; 10 | using MoviesAPI.Services; 11 | 12 | namespace MoviesAPI 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | CreateHostBuilder(args).Build().Run(); 19 | } 20 | 21 | public static IHostBuilder CreateHostBuilder(string[] args) => 22 | Host.CreateDefaultBuilder(args) 23 | .ConfigureWebHostDefaults(webBuilder => 24 | { 25 | webBuilder.UseStartup(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 5 - Configurations/End/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "lastname": "Gavilan", 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | }, 10 | "AllowedHosts": "*", 11 | "ConnectionStrings": { 12 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 13 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/GenreDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class GenreDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 5 - Configurations/Start/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/EditRoleDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class EditRoleDTO 9 | { 10 | public string UserId { get; set; } 11 | public string RoleName { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/GenreDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class GenreDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/HashResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class HashResult 9 | { 10 | public string Hash { get; set; } 11 | public byte[] Salt { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/UserDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserDTO 9 | { 10 | public string EmailAddress { get; set; } 11 | public string UserId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class UserInfo 10 | { 11 | [EmailAddress] 12 | [Required] 13 | public string EmailAddress { get; set; } 14 | [Required] 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/DTOs/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserToken 9 | { 10 | public string Token { get; set; } 11 | public DateTime Expiration { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Migrations/20200227021523_AdminRole.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace MoviesAPI.Migrations 4 | { 5 | public partial class AdminRole : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.Sql(@" 10 | Insert into AspNetRoles (Id, [name], [NormalizedName]) 11 | values ('af207a62-e683-48d6-9023-6acc163f7dd4', 'Admin', 'Admin') 12 | "); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.Sql(@"delete AspNetRoles 18 | where id = 'af207a62-e683-48d6-9023-6acc163f7dd4'"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using MoviesAPI.Controllers; 10 | using MoviesAPI.Services; 11 | 12 | namespace MoviesAPI 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | CreateHostBuilder(args).Build().Run(); 19 | } 20 | 21 | public static IHostBuilder CreateHostBuilder(string[] args) => 22 | Host.CreateDefaultBuilder(args) 23 | .ConfigureWebHostDefaults(webBuilder => 24 | { 25 | webBuilder.UseStartup(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 6 - Security/End/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | }, 14 | "jwt": { 15 | "key": "SADKMASLDMSKDSFKLSDNFLKSDMFLKMRKLMRELKTMERLK" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/GenreDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class GenreDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using MoviesAPI.Controllers; 10 | using MoviesAPI.Services; 11 | 12 | namespace MoviesAPI 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | CreateHostBuilder(args).Build().Run(); 19 | } 20 | 21 | public static IHostBuilder CreateHostBuilder(string[] args) => 22 | Host.CreateDefaultBuilder(args) 23 | .ConfigureWebHostDefaults(webBuilder => 24 | { 25 | webBuilder.UseStartup(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 6 - Security/Start/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Controllers/DefaultController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Controllers 8 | { 9 | [ApiExplorerSettings(IgnoreApi = true)] 10 | public class DefaultController: ControllerBase 11 | { 12 | [Route("/")] 13 | [Route("/swagger")] 14 | public RedirectResult Index() 15 | { 16 | return new RedirectResult("~/swagger"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Controllers/V2/RootController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using MoviesAPI.DTOs; 3 | using MoviesAPI.Helpers; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.Controllers.V2 10 | { 11 | [ApiController] 12 | [Route("api2")] 13 | //[HttpHeaderIsPresent("x-version", "2")] 14 | public class RootController: ControllerBase 15 | { 16 | [HttpGet(Name = "getRoot2")] 17 | public ActionResult> Get() 18 | { 19 | List links = new List(); 20 | 21 | links.Add(new Link(href: Url.Link("getRoot", new { }), rel: "self", method: "GET")); 22 | 23 | return links; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/EditRoleDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class EditRoleDTO 9 | { 10 | public string UserId { get; set; } 11 | public string RoleName { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/HashResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class HashResult 9 | { 10 | public string Hash { get; set; } 11 | public byte[] Salt { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/IGenerateHATEOASLinks.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public interface IGenerateHATEOASLinks 10 | { 11 | void GenerateLinks(IUrlHelper urlHelper); 12 | ResourceCollection GenerateLinksCollection(List dtos, IUrlHelper urlHelper); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/Link.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class Link 9 | { 10 | public string Href { get; set; } 11 | public string Rel { get; set; } 12 | public string Method { get; set; } 13 | 14 | public Link(string href, string rel, string method) 15 | { 16 | Href = href; 17 | Rel = rel; 18 | Method = method; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/MovieTheatherDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieTheaterDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public double DistanceInMeters { get; set; } 13 | public double DistanceInKms { get { return DistanceInMeters / 1000; } } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/ResourceCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ResourceCollection 9 | { 10 | public List Values { get; set; } 11 | public List Links { get; set; } = new List(); 12 | 13 | public ResourceCollection(List values) 14 | { 15 | Values = values; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/UserDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserDTO 9 | { 10 | public string EmailAddress { get; set; } 11 | public string UserId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class UserInfo 10 | { 11 | [EmailAddress] 12 | [Required] 13 | public string EmailAddress { get; set; } 14 | [Required] 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/DTOs/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserToken 9 | { 10 | public string Token { get; set; } 11 | public DateTime Expiration { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre: IId 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Entities/IId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public interface IId 9 | { 10 | public int Id { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Entities/MovieTheater.cs: -------------------------------------------------------------------------------- 1 | using NetTopologySuite.Geometries; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class MovieTheater 11 | { 12 | public int Id { get; set; } 13 | [Required] 14 | public string Name { get; set; } 15 | public Point Location { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Migrations/20200227021523_AdminRole.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace MoviesAPI.Migrations 4 | { 5 | public partial class AdminRole : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.Sql(@" 10 | Insert into AspNetRoles (Id, [name], [NormalizedName]) 11 | values ('af207a62-e683-48d6-9023-6acc163f7dd4', 'Admin', 'Admin') 12 | "); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.Sql(@"delete AspNetRoles 18 | where id = 'af207a62-e683-48d6-9023-6acc163f7dd4'"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavilanch/MoviesAPI/b6cd704ede774f0c32e6f56cd1c757eab5029072/Module 7 - Advanced Scenarios/End/MoviesAPI/Startup.cs -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/End/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | }, 14 | "jwt": { 15 | "key": "SADKMASLDMSKDSFKLSDNFLKSDMFLKMRKLMRELKTMERLK" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/EditRoleDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class EditRoleDTO 9 | { 10 | public string UserId { get; set; } 11 | public string RoleName { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/GenreDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class GenreDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/HashResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class HashResult 9 | { 10 | public string Hash { get; set; } 11 | public byte[] Salt { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/UserDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserDTO 9 | { 10 | public string EmailAddress { get; set; } 11 | public string UserId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class UserInfo 10 | { 11 | [EmailAddress] 12 | [Required] 13 | public string EmailAddress { get; set; } 14 | [Required] 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/DTOs/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserToken 9 | { 10 | public string Token { get; set; } 11 | public DateTime Expiration { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Migrations/20200227021523_AdminRole.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace MoviesAPI.Migrations 4 | { 5 | public partial class AdminRole : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.Sql(@" 10 | Insert into AspNetRoles (Id, [name], [NormalizedName]) 11 | values ('af207a62-e683-48d6-9023-6acc163f7dd4', 'Admin', 'Admin') 12 | "); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.Sql(@"delete AspNetRoles 18 | where id = 'af207a62-e683-48d6-9023-6acc163f7dd4'"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 7 - Advanced Scenarios/Start/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | }, 14 | "jwt": { 15 | "key": "SADKMASLDMSKDSFKLSDNFLKSDMFLKMRKLMRELKTMERLK" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI.Tests/AllowAnonymousHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Tests 8 | { 9 | public class AllowAnonymousHandler : IAuthorizationHandler 10 | { 11 | public Task HandleAsync(AuthorizationHandlerContext context) 12 | { 13 | foreach (var requirement in context.PendingRequirements.ToList()) 14 | { 15 | context.Succeed(requirement); 16 | } 17 | 18 | return Task.CompletedTask; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI.Tests/FakeUserFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Tests 9 | { 10 | public class FakeUserFilter : IAsyncActionFilter 11 | { 12 | public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 13 | { 14 | context.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new List 15 | { 16 | new Claim(ClaimTypes.Email, "example@hotmail.com") 17 | }, "Test")); 18 | 19 | await next(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI.Tests/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:65045/", 7 | "sslPort": 44353 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "MoviesAPI.Tests": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Controllers/DefaultController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Controllers 8 | { 9 | [ApiExplorerSettings(IgnoreApi = true)] 10 | public class DefaultController: ControllerBase 11 | { 12 | [Route("/")] 13 | [Route("/swagger")] 14 | public RedirectResult Index() 15 | { 16 | return new RedirectResult("~/swagger"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/EditRoleDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class EditRoleDTO 9 | { 10 | public string UserId { get; set; } 11 | public string RoleName { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/HashResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class HashResult 9 | { 10 | public string Hash { get; set; } 11 | public byte[] Salt { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/IGenerateHATEOASLinks.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public interface IGenerateHATEOASLinks 10 | { 11 | void GenerateLinks(IUrlHelper urlHelper); 12 | ResourceCollection GenerateLinksCollection(List dtos, IUrlHelper urlHelper); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/Link.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class Link 9 | { 10 | public string Href { get; set; } 11 | public string Rel { get; set; } 12 | public string Method { get; set; } 13 | 14 | public Link(string href, string rel, string method) 15 | { 16 | Href = href; 17 | Rel = rel; 18 | Method = method; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/MovieTheatherDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieTheaterDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public double DistanceInMeters { get; set; } 13 | public double DistanceInKms { get { return DistanceInMeters / 1000; } } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/ResourceCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ResourceCollection 9 | { 10 | public List Values { get; set; } 11 | public List Links { get; set; } = new List(); 12 | 13 | public ResourceCollection(List values) 14 | { 15 | Values = values; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/UserDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserDTO 9 | { 10 | public string EmailAddress { get; set; } 11 | public string UserId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class UserInfo 10 | { 11 | [EmailAddress] 12 | [Required] 13 | public string EmailAddress { get; set; } 14 | [Required] 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/DTOs/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserToken 9 | { 10 | public string Token { get; set; } 11 | public DateTime Expiration { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre: IId 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Entities/IId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public interface IId 9 | { 10 | public int Id { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Entities/MovieTheater.cs: -------------------------------------------------------------------------------- 1 | using NetTopologySuite.Geometries; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class MovieTheater 11 | { 12 | public int Id { get; set; } 13 | [Required] 14 | public string Name { get; set; } 15 | public Point Location { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Migrations/20200227021523_AdminRole.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace MoviesAPI.Migrations 4 | { 5 | public partial class AdminRole : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.Sql(@" 10 | Insert into AspNetRoles (Id, [name], [NormalizedName]) 11 | values ('af207a62-e683-48d6-9023-6acc163f7dd4', 'Admin', 'Admin') 12 | "); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.Sql(@"delete AspNetRoles 18 | where id = 'af207a62-e683-48d6-9023-6acc163f7dd4'"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using MoviesAPI.Controllers; 10 | using MoviesAPI.Services; 11 | 12 | namespace MoviesAPI 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | CreateHostBuilder(args).Build().Run(); 19 | } 20 | 21 | public static IHostBuilder CreateHostBuilder(string[] args) => 22 | Host.CreateDefaultBuilder(args) 23 | .ConfigureWebHostDefaults(webBuilder => 24 | { 25 | webBuilder.UseStartup(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavilanch/MoviesAPI/b6cd704ede774f0c32e6f56cd1c757eab5029072/Module 8 - Testing/End/MoviesAPI/Startup.cs -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Testing/Account.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Testing 7 | { 8 | public class Account 9 | { 10 | public decimal Funds { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Testing/IValidateWireTransfer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Testing 7 | { 8 | public interface IValidateWireTransfer 9 | { 10 | OperationResult Validate(Account origin, Account destination, decimal amount); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Testing/OperationResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Testing 7 | { 8 | public class OperationResult 9 | { 10 | public OperationResult(bool isSuccessful, string errorMessage = null) 11 | { 12 | IsSuccessful = isSuccessful; 13 | ErrorMessage = errorMessage; 14 | } 15 | public bool IsSuccessful { get; set; } 16 | public string ErrorMessage { get; set; } 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/Testing/WireTransferValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Testing 7 | { 8 | public class WireTransferValidator : IValidateWireTransfer 9 | { 10 | public OperationResult Validate(Account origin, Account destination, decimal amount) 11 | { 12 | if (amount > origin.Funds) 13 | { 14 | return new OperationResult(false, "The origin account does not have enough funds available"); 15 | } 16 | 17 | // other validations 18 | 19 | return new OperationResult(true); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 8 - Testing/End/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | }, 14 | "jwt": { 15 | "key": "SADKMASLDMSKDSFKLSDNFLKSDMFLKMRKLMRELKTMERLK" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Controllers/DefaultController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Controllers 8 | { 9 | [ApiExplorerSettings(IgnoreApi = true)] 10 | public class DefaultController: ControllerBase 11 | { 12 | [Route("/")] 13 | [Route("/swagger")] 14 | public RedirectResult Index() 15 | { 16 | return new RedirectResult("~/swagger"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/EditRoleDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class EditRoleDTO 9 | { 10 | public string UserId { get; set; } 11 | public string RoleName { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/HashResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class HashResult 9 | { 10 | public string Hash { get; set; } 11 | public byte[] Salt { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/IGenerateHATEOASLinks.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public interface IGenerateHATEOASLinks 10 | { 11 | void GenerateLinks(IUrlHelper urlHelper); 12 | ResourceCollection GenerateLinksCollection(List dtos, IUrlHelper urlHelper); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/Link.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class Link 9 | { 10 | public string Href { get; set; } 11 | public string Rel { get; set; } 12 | public string Method { get; set; } 13 | 14 | public Link(string href, string rel, string method) 15 | { 16 | Href = href; 17 | Rel = rel; 18 | Method = method; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/MovieTheatherDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieTheaterDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public double DistanceInMeters { get; set; } 13 | public double DistanceInKms { get { return DistanceInMeters / 1000; } } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/ResourceCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ResourceCollection 9 | { 10 | public List Values { get; set; } 11 | public List Links { get; set; } = new List(); 12 | 13 | public ResourceCollection(List values) 14 | { 15 | Values = values; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/UserDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserDTO 9 | { 10 | public string EmailAddress { get; set; } 11 | public string UserId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class UserInfo 10 | { 11 | [EmailAddress] 12 | [Required] 13 | public string EmailAddress { get; set; } 14 | [Required] 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/DTOs/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserToken 9 | { 10 | public string Token { get; set; } 11 | public DateTime Expiration { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre: IId 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Entities/IId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public interface IId 9 | { 10 | public int Id { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Entities/MovieTheater.cs: -------------------------------------------------------------------------------- 1 | using NetTopologySuite.Geometries; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class MovieTheater 11 | { 12 | public int Id { get; set; } 13 | [Required] 14 | public string Name { get; set; } 15 | public Point Location { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Migrations/20200227021523_AdminRole.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace MoviesAPI.Migrations 4 | { 5 | public partial class AdminRole : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.Sql(@" 10 | Insert into AspNetRoles (Id, [name], [NormalizedName]) 11 | values ('af207a62-e683-48d6-9023-6acc163f7dd4', 'Admin', 'Admin') 12 | "); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.Sql(@"delete AspNetRoles 18 | where id = 'af207a62-e683-48d6-9023-6acc163f7dd4'"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using MoviesAPI.Controllers; 10 | using MoviesAPI.Services; 11 | 12 | namespace MoviesAPI 13 | { 14 | public class Program 15 | { 16 | public static void Main(string[] args) 17 | { 18 | CreateHostBuilder(args).Build().Run(); 19 | } 20 | 21 | public static IHostBuilder CreateHostBuilder(string[] args) => 22 | Host.CreateDefaultBuilder(args) 23 | .ConfigureWebHostDefaults(webBuilder => 24 | { 25 | webBuilder.UseStartup(); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavilanch/MoviesAPI/b6cd704ede774f0c32e6f56cd1c757eab5029072/Module 8 - Testing/Start/MoviesAPI/Startup.cs -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Module 8 - Testing/Start/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "ConnectionStrings": { 11 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 12 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 13 | }, 14 | "jwt": { 15 | "key": "SADKMASLDMSKDSFKLSDNFLKSDMFLKMRKLMRELKTMERLK" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI.Tests/AllowAnonymousHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Tests 8 | { 9 | public class AllowAnonymousHandler : IAuthorizationHandler 10 | { 11 | public Task HandleAsync(AuthorizationHandlerContext context) 12 | { 13 | foreach (var requirement in context.PendingRequirements.ToList()) 14 | { 15 | context.Succeed(requirement); 16 | } 17 | 18 | return Task.CompletedTask; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI.Tests/FakeUserFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Tests 9 | { 10 | public class FakeUserFilter : IAsyncActionFilter 11 | { 12 | public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) 13 | { 14 | context.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new List 15 | { 16 | new Claim(ClaimTypes.Email, "example@hotmail.com") 17 | }, "Test")); 18 | 19 | await next(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI.Tests/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:65045/", 7 | "sslPort": 44353 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "MoviesAPI.Tests": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Controllers/DefaultController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Controllers 8 | { 9 | [ApiExplorerSettings(IgnoreApi = true)] 10 | public class DefaultController: ControllerBase 11 | { 12 | [Route("/")] 13 | [Route("/swagger")] 14 | public RedirectResult Index() 15 | { 16 | return new RedirectResult("~/swagger"); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/ActorCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorCreationDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/ActorDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ActorDTO 9 | { 10 | public int PersonId { get; set; } 11 | public string Character { get; set; } 12 | public string PersonName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/EditRoleDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class EditRoleDTO 9 | { 10 | public string UserId { get; set; } 11 | public string RoleName { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/FilterMoviesDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class FilterMoviesDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | public int RecordsPerPage { get; set; } = 10; 12 | public PaginationDTO Pagination 13 | { 14 | get { return new PaginationDTO() { Page = Page, RecordsPerPage = RecordsPerPage }; } 15 | } 16 | public string Title { get; set; } 17 | public int GenreId { get; set; } 18 | public bool InTheaters { get; set; } 19 | public bool UpcomingReleases { get; set; } 20 | public string OrderingField { get; set; } 21 | public bool AscendingOrder { get; set; } = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/GenreCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.DTOs 9 | { 10 | public class GenreCreationDTO 11 | { 12 | [Required] 13 | [StringLength(40)] 14 | [FirstLetterUppercase] 15 | public string Name { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/HashResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class HashResult 9 | { 10 | public string Hash { get; set; } 11 | public byte[] Salt { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/IGenerateHATEOASLinks.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public interface IGenerateHATEOASLinks 10 | { 11 | void GenerateLinks(IUrlHelper urlHelper); 12 | ResourceCollection GenerateLinksCollection(List dtos, IUrlHelper urlHelper); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/IndexMoviePageDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class IndexMoviePageDTO 9 | { 10 | public List UpcomingReleases { get; set; } 11 | public List InTheaters { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/Link.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class Link 9 | { 10 | public string Href { get; set; } 11 | public string Rel { get; set; } 12 | public string Method { get; set; } 13 | 14 | public Link(string href, string rel, string method) 15 | { 16 | Href = href; 17 | Rel = rel; 18 | Method = method; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/MovieDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDTO 9 | { 10 | public int Id { get; set; } 11 | public string Title { get; set; } 12 | public string Summary { get; set; } 13 | public bool InTheaters { get; set; } 14 | public DateTime ReleaseDate { get; set; } 15 | public string Poster { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/MovieDetailsDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieDetailsDTO: MovieDTO 9 | { 10 | public List Genres { get; set; } 11 | public List Actors { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/MoviePatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class MoviePatchDTO 10 | { 11 | [Required] 12 | [StringLength(300)] 13 | public string Title { get; set; } 14 | public string Summary { get; set; } 15 | public bool InTheaters { get; set; } 16 | public DateTime ReleaseDate { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/MovieTheatherDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class MovieTheaterDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public double DistanceInMeters { get; set; } 13 | public double DistanceInKms { get { return DistanceInMeters / 1000; } } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/PaginationDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PaginationDTO 9 | { 10 | public int Page { get; set; } = 1; 11 | 12 | private int recordsPerPage = 10; 13 | private readonly int maxRecordsPerPage = 50; 14 | 15 | public int RecordsPerPage 16 | { 17 | get 18 | { 19 | return recordsPerPage; 20 | } 21 | set 22 | { 23 | recordsPerPage = (value > maxRecordsPerPage) ? maxRecordsPerPage : value; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/PersonCreationDTO.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using MoviesAPI.Validations; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MoviesAPI.DTOs 10 | { 11 | public class PersonCreationDTO: PersonPatchDTO 12 | { 13 | [FileSizeValidator(MaxFileSizeInMbs: 4)] 14 | [ContentTypeValidator(ContentTypeGroup.Image)] 15 | public IFormFile Picture { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/PersonDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class PersonDTO 9 | { 10 | public int Id { get; set; } 11 | public string Name { get; set; } 12 | public string Biography { get; set; } 13 | public DateTime DateOfBirth { get; set; } 14 | public string Picture { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/PersonPatchDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class PersonPatchDTO 10 | { 11 | [Required] 12 | [StringLength(120)] 13 | public string Name { get; set; } 14 | public string Biography { get; set; } 15 | public DateTime DateOfBirth { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/ResourceCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class ResourceCollection 9 | { 10 | public List Values { get; set; } 11 | public List Links { get; set; } = new List(); 12 | 13 | public ResourceCollection(List values) 14 | { 15 | Values = values; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/UserDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserDTO 9 | { 10 | public string EmailAddress { get; set; } 11 | public string UserId { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/UserInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.DTOs 8 | { 9 | public class UserInfo 10 | { 11 | [EmailAddress] 12 | [Required] 13 | public string EmailAddress { get; set; } 14 | [Required] 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/DTOs/UserToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.DTOs 7 | { 8 | public class UserToken 9 | { 10 | public string Token { get; set; } 11 | public DateTime Expiration { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Entities/Genre.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.Validations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class Genre: IId 11 | { 12 | public int Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(40)] 16 | [FirstLetterUppercase] 17 | public string Name { get; set; } 18 | 19 | public List MoviesGenres { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Entities/IId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public interface IId 9 | { 10 | public int Id { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Entities/Movie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Movie: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(300)] 14 | public string Title { get; set; } 15 | public string Summary { get; set; } 16 | public bool InTheaters { get; set; } 17 | public DateTime ReleaseDate { get; set; } 18 | public string Poster { get; set; } 19 | public List MoviesActors { get; set; } 20 | public List MoviesGenres { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Entities/MovieTheater.cs: -------------------------------------------------------------------------------- 1 | using NetTopologySuite.Geometries; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Entities 9 | { 10 | public class MovieTheater 11 | { 12 | public int Id { get; set; } 13 | [Required] 14 | public string Name { get; set; } 15 | public Point Location { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Entities/MoviesActors.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesActors 9 | { 10 | public int PersonId { get; set; } 11 | public int MovieId { get; set; } 12 | public Person Person { get; set; } 13 | public Movie Movie { get; set; } 14 | public string Character { get; set; } 15 | public int Order { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Entities/MoviesGenres.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Entities 7 | { 8 | public class MoviesGenres 9 | { 10 | public int MovieId { get; set; } 11 | public int GenreId { get; set; } 12 | public Movie Movie { get; set; } 13 | public Genre Genre { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Entities/Person.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Entities 8 | { 9 | public class Person: IId 10 | { 11 | public int Id { get; set; } 12 | [Required] 13 | [StringLength(120)] 14 | public string Name { get; set; } 15 | public string Biography { get; set; } 16 | public DateTime DateOfBirth { get; set; } 17 | public string Picture { get; set; } 18 | 19 | public List MoviesActors { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Filters/MyExceptionFilter.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.Filters; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MoviesAPI.Filters 9 | { 10 | public class MyExceptionFilter: ExceptionFilterAttribute 11 | { 12 | private readonly ILogger logger; 13 | 14 | public MyExceptionFilter(ILogger logger) 15 | { 16 | this.logger = logger; 17 | } 18 | 19 | public override void OnException(ExceptionContext context) 20 | { 21 | logger.LogError(context.Exception, context.Exception.Message); 22 | 23 | base.OnException(context); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Helpers/QueryableExtensions.cs: -------------------------------------------------------------------------------- 1 | using MoviesAPI.DTOs; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MoviesAPI.Helpers 8 | { 9 | public static class QueryableExtensions 10 | { 11 | public static IQueryable Paginate(this IQueryable queryable, PaginationDTO pagination) 12 | { 13 | return queryable 14 | .Skip((pagination.Page - 1) * pagination.RecordsPerPage) 15 | .Take(pagination.RecordsPerPage); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Migrations/20200227021523_AdminRole.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace MoviesAPI.Migrations 4 | { 5 | public partial class AdminRole : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.Sql(@" 10 | Insert into AspNetRoles (Id, [name], [NormalizedName]) 11 | values ('af207a62-e683-48d6-9023-6acc163f7dd4', 'Admin', 'Admin') 12 | "); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.Sql(@"delete AspNetRoles 18 | where id = 'af207a62-e683-48d6-9023-6acc163f7dd4'"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Migrations/20200313024102_Temp1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace MoviesAPI.Migrations 4 | { 5 | public partial class Temp1 : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.InsertData( 10 | table: "Genres", 11 | columns: new[] { "Id", "Name" }, 12 | values: new object[] { 9, "Temp Genre" }); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.DeleteData( 18 | table: "Genres", 19 | keyColumn: "Id", 20 | keyValue: 9); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Services/IFileStorageService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MoviesAPI.Services 7 | { 8 | public interface IFileStorageService 9 | { 10 | Task EditFile(byte[] content, string extension, string containerName, string fileRoute, string contentType); 11 | Task DeleteFile(string fileRoute, string containerName); 12 | Task SaveFile(byte[] content, string extension, string containerName, string contentType); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/Startup.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gavilanch/MoviesAPI/b6cd704ede774f0c32e6f56cd1c757eab5029072/Module 9 - Deployment/AzureAppService/MoviesAPI/Startup.cs -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "MoviesAPI": "Warning", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | }, 10 | "ApplicationInsights": { 11 | "InstrumentationKey": "0000000000000000000000" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Module 9 - Deployment/AzureAppService/MoviesAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "ApplicationInsights": { 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "Microsoft": "Error" 7 | } 8 | }, 9 | "LogLevel": { 10 | "Default": "Information", 11 | "Microsoft": "Warning", 12 | "Microsoft.Hosting.Lifetime": "Information" 13 | } 14 | }, 15 | "AllowedHosts": "*", 16 | "ConnectionStrings": { 17 | "DefaultConnection": "Data Source=.;Initial Catalog=MoviesAPI;Integrated Security=True", 18 | "AzureStorageConnection": "DefaultEndpointsProtocol=https;AccountName=moviesapi;AccountKey=6yy8zxOplPXDvgURf/eLbco2NALojoKNfazxYgzMIs17ydFkz9VAS2FH7RjuuOa+ty0ajpaBkxHbqzO8KvTo9A==;EndpointSuffix=core.windows.net" 19 | }, 20 | "jwt": { 21 | "key": "SADKMASLDMSKDSFKLSDNFLKSDMFLKMRKLMRELKTMERLK" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Repository of the course: Building RESTful Web APIs with ASP.NET Core 3.1 2 | 3 | Link of the course: https://felipe-gavilan.azurewebsites.net/api/Redireccion?curso=building-restful-web-apis-asp-net-core-eng 4 | 5 | In this repository you will find the source code for my course on Building RESTful Web APIs with ASP.NET Core. 6 | 7 | Thanks! 8 | --------------------------------------------------------------------------------