-
Notifications
You must be signed in to change notification settings - Fork 3
kailin parking lot api #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
a2a3875
e5a1f52
d3d61a9
7cdbe4e
3913a4e
65957b3
b87ecc8
a042518
0cc6ca6
c824740
361ff18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using ParkingLotApi.Dtos; | ||
| using ParkingLotApi.Exceptions; | ||
| using ParkingLotApi.Models; | ||
| using ParkingLotApi.Services; | ||
|
|
||
| namespace ParkingLotApi.Controllers | ||
| { | ||
| [ApiController] | ||
| [Route("[controller]")] | ||
| public class ParkingLotsController : ControllerBase | ||
| { | ||
| private ParkingLotService parkingLotService; | ||
|
|
||
| public ParkingLotsController(ParkingLotService parkingLotService) | ||
| { | ||
| this.parkingLotService = parkingLotService; | ||
| } | ||
|
|
||
| [HttpPost] | ||
| public async Task<ActionResult<ParkingLotDto>> CreateParkingLotAsync([FromBody] ParkingLotDto parkingLotDto) | ||
| { | ||
| //try | ||
| //{ | ||
| return StatusCode(StatusCodes.Status201Created, await parkingLotService.CreateAsync(parkingLotDto)); | ||
| //} | ||
| //catch (InvalidCapacityException ex) | ||
| //{ | ||
| // return BadRequest(); | ||
| //} | ||
| } | ||
|
|
||
| [HttpDelete("id")] | ||
| public async Task<ActionResult<ParkingLotDto>> DeleteParkingLotAsync(string id) | ||
| { | ||
| await parkingLotService.DeleteParkingLot(id); | ||
| return new NoContentResult(); | ||
| } | ||
|
|
||
| [HttpGet] | ||
| public async Task<ActionResult<List<ParkingLot>>> GetParkingLotsByPageInfoAsync(int pageIndex) | ||
| { | ||
| return await parkingLotService.GetParkingLotByPageInfo(pageIndex); | ||
| } | ||
|
|
||
| [HttpGet("{id}")] | ||
| public async Task<ActionResult<ParkingLot>> GetParkingLotByIdAsync(string id) | ||
| { | ||
| return await parkingLotService.GetParkingLotById(id); | ||
| } | ||
|
|
||
| [HttpPut("{id}")] | ||
| public async Task<ActionResult<ParkingLot>> UpdateParkingLotAsync(string id, [FromBody] ParkingLotDto parkingLotDto) | ||
| { | ||
| return await parkingLotService.UpdateParkingLot(id, parkingLotDto); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| using ParkingLotApi.Models; | ||
|
|
||
| namespace ParkingLotApi.Dtos | ||
| { | ||
| public class ParkingLotDto | ||
| { | ||
| public string Name { get; set; } | ||
| public int Capacity { get; set; } | ||
| public string Location { get; set; } | ||
|
|
||
| internal ParkingLot ToEntity() | ||
| { | ||
| return new ParkingLot() | ||
| { | ||
| Name = this.Name, | ||
| Capacity = this.Capacity, | ||
| Location = this.Location | ||
| }; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| namespace ParkingLotApi.Exceptions | ||
| { | ||
| public class InvalidCapacityException : Exception | ||
| { | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| namespace ParkingLotApi.Exceptions | ||
| { | ||
| public class PageInfoInvalidException : Exception | ||
| { | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| namespace ParkingLotApi.Exceptions | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well: nice to define customized exception |
||
| { | ||
| public class ParkingLotNotFoundException : Exception | ||
| { | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| using Microsoft.AspNetCore.Http.HttpResults; | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using Microsoft.AspNetCore.Mvc.Filters; | ||
| using ParkingLotApi.Exceptions; | ||
|
|
||
| namespace ParkingLotApi.Filters | ||
| { | ||
| public class InvalidCapacityExceptionFilter : IActionFilter, IOrderedFilter | ||
| { | ||
| int IOrderedFilter.Order => int.MaxValue - 10; | ||
|
|
||
| void IActionFilter.OnActionExecuted(ActionExecutedContext context) | ||
| { | ||
| if (context.Exception is InvalidCapacityException invalidCapacityException) | ||
| { | ||
| context.Result = new BadRequestResult(); | ||
| context.ExceptionHandled = true; | ||
| } | ||
| } | ||
|
|
||
| void IActionFilter.OnActionExecuting(ActionExecutingContext context) | ||
| { | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using Microsoft.AspNetCore.Mvc.Filters; | ||
| using ParkingLotApi.Exceptions; | ||
|
|
||
| namespace ParkingLotApi.Filters | ||
| { | ||
| public class PageInfoInvalidExceptionFilter : IActionFilter, IOrderedFilter | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well: nice to add more than one exception filter |
||
| { | ||
| int IOrderedFilter.Order => int.MaxValue - 10; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: this value might need to be different for each filter |
||
|
|
||
| void IActionFilter.OnActionExecuted(ActionExecutedContext context) | ||
| { | ||
| if (context.Exception is PageInfoInvalidException pageInfoInvalidException) | ||
| { | ||
| context.Result = new BadRequestObjectResult(context.Exception.Message); | ||
| context.ExceptionHandled = true; | ||
| } | ||
| } | ||
|
|
||
| void IActionFilter.OnActionExecuting(ActionExecutingContext context) | ||
| { | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| using Microsoft.AspNetCore.Mvc.Filters; | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using ParkingLotApi.Exceptions; | ||
|
|
||
| namespace ParkingLotApi.Filters | ||
| { | ||
| public class ParkingLotNotFoundExceptionFilter :IActionFilter, IOrderedFilter | ||
| { | ||
| int IOrderedFilter.Order => int.MaxValue - 10; | ||
|
|
||
| void IActionFilter.OnActionExecuted(ActionExecutedContext context) | ||
| { | ||
| if (context.Exception is ParkingLotNotFoundException parkingLotNotFoundException) | ||
| { | ||
| context.Result = new NotFoundObjectResult(context.Exception.Message); | ||
| context.ExceptionHandled = true; | ||
| } | ||
| } | ||
|
|
||
| void IActionFilter.OnActionExecuting(ActionExecutingContext context) | ||
| { | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| using MongoDB.Bson; | ||
| using MongoDB.Bson.Serialization.Attributes; | ||
|
|
||
| namespace ParkingLotApi.Models | ||
| { | ||
| public class ParkingLot | ||
| { | ||
| [BsonId] | ||
| [BsonRepresentation(BsonType.ObjectId)] | ||
| public string? Id { get; set; } | ||
| public string Name { get; set; } | ||
| public int Capacity { get; set; } | ||
| public string Location { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| namespace ParkingLotApi.Models | ||
| { | ||
| public class ParkingLotDatabaseSettings | ||
| { | ||
| public string ConnectionString { get; set; } = null!; | ||
| public string DatabaseName { get; set; } = null!; | ||
| public string CollectionName { get; set; } = null!; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| using ParkingLotApi.Models; | ||
|
|
||
| namespace ParkingLotApi.Repositories | ||
| { | ||
| public interface IParkingLotsRepository | ||
| { | ||
| public Task<ParkingLot> CreateParkingLot(ParkingLot parking); | ||
| public Task<ParkingLot> GetParkingLotById(string id); | ||
| public Task DeleteParkingLotById(string id); | ||
| public Task<List<ParkingLot>> GetParkingLotByPageInfo(int pageIndex, int pageSize); | ||
| public Task<List<ParkingLot>> GetAllParkingLot(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: there is no requirement for getting all data |
||
| public Task<ParkingLot> UpdateParkingLotInfo(string id, ParkingLot parkingLot); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| using Microsoft.Extensions.Options; | ||
| using MongoDB.Driver; | ||
| using ParkingLotApi.Models; | ||
|
|
||
| namespace ParkingLotApi.Repositories | ||
| { | ||
| public class ParkingLotsRepository : IParkingLotsRepository | ||
| { | ||
| private readonly IMongoCollection<ParkingLot> parkingLotCollection; | ||
|
|
||
| public ParkingLotsRepository(IOptions<ParkingLotDatabaseSettings> parkingLotDatabaseSettings) | ||
| { | ||
| var mongoClient = new MongoClient(parkingLotDatabaseSettings.Value.ConnectionString); | ||
| var mongoDatabase = mongoClient.GetDatabase(parkingLotDatabaseSettings.Value.DatabaseName); | ||
| parkingLotCollection = mongoDatabase.GetCollection<ParkingLot>(parkingLotDatabaseSettings.Value.CollectionName); | ||
| } | ||
|
|
||
| public async Task<ParkingLot> CreateParkingLot(ParkingLot parkingLot) | ||
| { | ||
| await parkingLotCollection.InsertOneAsync(parkingLot); | ||
| return await parkingLotCollection.Find(a => a.Name == parkingLot.Name).FirstAsync(); | ||
| } | ||
|
|
||
| public async Task<ParkingLot> GetParkingLotById(string id) | ||
| { | ||
| return await parkingLotCollection.Find(parkingLot => parkingLot.Id == id).FirstOrDefaultAsync(); | ||
| } | ||
|
|
||
| public async Task DeleteParkingLotById(string id) | ||
| { | ||
| await parkingLotCollection.DeleteOneAsync(parkingLot => parkingLot.Id == id); | ||
| } | ||
|
|
||
| public async Task<List<ParkingLot>> GetParkingLotByPageInfo(int pageIndex, int pageSize) | ||
| { | ||
| return await parkingLotCollection.Find(parkingLot => true) | ||
| .Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync(); | ||
| } | ||
|
|
||
| public async Task<List<ParkingLot>> GetAllParkingLot() | ||
| { | ||
| return await parkingLotCollection.Find(parkingLot => true).ToListAsync(); | ||
| } | ||
|
|
||
| public async Task<ParkingLot> UpdateParkingLotInfo(string id, ParkingLot parkingLot) | ||
| { | ||
| await parkingLotCollection.ReplaceOneAsync(parkingLot => parkingLot.Id == id, parkingLot); | ||
| return parkingLot; | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| using ParkingLotApi.Dtos; | ||
| using ParkingLotApi.Exceptions; | ||
| using ParkingLotApi.Models; | ||
| using ParkingLotApi.Repositories; | ||
|
|
||
| namespace ParkingLotApi.Services | ||
| { | ||
| public class ParkingLotService | ||
| { | ||
| private readonly IParkingLotsRepository parkingLotsRepository; | ||
|
|
||
| public ParkingLotService(IParkingLotsRepository parkingLotsRepository) | ||
| { | ||
| this.parkingLotsRepository = parkingLotsRepository; | ||
| } | ||
|
|
||
| public async Task<ParkingLot> CreateAsync(ParkingLotDto parkingLotDto) | ||
| { | ||
| if (parkingLotDto.Capacity < 10) | ||
| { | ||
| throw new InvalidCapacityException(); | ||
| } | ||
|
|
||
| return await parkingLotsRepository.CreateParkingLot(parkingLotDto.ToEntity()); | ||
| } | ||
|
|
||
| public async Task DeleteParkingLot(string id) | ||
| { | ||
| if (await parkingLotsRepository.GetParkingLotById(id) == null) | ||
| { | ||
| throw new ParkingLotNotFoundException(); | ||
| } | ||
| await parkingLotsRepository.DeleteParkingLotById(id); | ||
| } | ||
|
|
||
| public async Task<List<ParkingLot>> GetParkingLotByPageInfo(int pageIndex) | ||
| { | ||
| int pageSize = 15; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: this variable can be extracted as constant |
||
|
|
||
| if (pageIndex < 0) | ||
| { | ||
| throw new PageInfoInvalidException(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good:throw exception in service |
||
| } | ||
|
|
||
| if (pageIndex == 0) | ||
| { | ||
| return await parkingLotsRepository.GetAllParkingLot(); | ||
| } | ||
| else | ||
| { | ||
| return await parkingLotsRepository.GetParkingLotByPageInfo(pageIndex, pageSize); | ||
| } | ||
| } | ||
|
|
||
| public async Task<ParkingLot> GetParkingLotById(string id) | ||
| { | ||
| ParkingLot parkingLot = await parkingLotsRepository.GetParkingLotById(id); | ||
|
|
||
| if (parkingLot == null) | ||
| { | ||
| throw new ParkingLotNotFoundException(); | ||
| } | ||
|
|
||
| return parkingLot; | ||
| } | ||
|
|
||
| public async Task<ParkingLot> UpdateParkingLot(string id, ParkingLotDto parkingLotDto) | ||
| { | ||
| ParkingLot parkingLot = await parkingLotsRepository.GetParkingLotById(id); | ||
|
|
||
| if (parkingLot == null) | ||
| { | ||
| throw new ParkingLotNotFoundException(); | ||
| } | ||
|
|
||
| parkingLot.Location = parkingLotDto.Location; | ||
| parkingLot.Capacity = (int)parkingLotDto.Capacity; | ||
|
|
||
| return await parkingLotsRepository.UpdateParkingLotInfo(id, parkingLot); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: remove dead code