-
Notifications
You must be signed in to change notification settings - Fork 3
Shuhan Jin-homework with adult step commit #5
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
89063b6
61a3e9d
e28b88a
4242d81
676ebb9
397f0d4
8cabc95
0677372
513ca5e
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,81 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using ParkingLotApi.Dtos; | ||
using ParkingLotApi.Exceptions; | ||
using ParkingLotApi.Models; | ||
using ParkingLotApi.Services; | ||
|
||
namespace ParkingLotApi.Controllers | ||
{ | ||
[ApiController] | ||
[Route("[controller]")] //Ĭ��ParkingLotsController��controllerǰ����ַ���·�� | ||
public class ParkingLotsController : ControllerBase | ||
{ | ||
private readonly ParkingLotsService _parkingLotsService; | ||
public ParkingLotsController(ParkingLotsService parkingLotsService) //��ParkingLotsServiceע�빹�캯�� | ||
{ | ||
_parkingLotsService = parkingLotsService; | ||
} | ||
|
||
[HttpPost] | ||
public async Task<ActionResult<ParkingLotDto>> AddParkingLotAsync([FromBody] ParkingLotDto parkingLotDto) | ||
{ | ||
//try | ||
//{ | ||
return StatusCode(StatusCodes.Status201Created, await _parkingLotsService.AddAsync(parkingLotDto)); | ||
//} | ||
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: |
||
//catch (InvalidCapacityException ex) | ||
//{ | ||
// return BadRequest(); | ||
//} | ||
|
||
//if (parkingLotDto.Capacity < 10) | ||
//{ | ||
// return BadRequest(); | ||
//} | ||
// return null; | ||
} | ||
|
||
[HttpDelete] | ||
public async Task<ActionResult> DeleteParkingLotAsync(string id) | ||
{ | ||
await _parkingLotsService.DeleteAsync(id); | ||
return NoContent(); | ||
} | ||
|
||
[HttpGet] | ||
public async Task<ActionResult<List<ParkingLot>>> GetOnePageAsync([FromQuery] int? pageIndex) | ||
{ | ||
if (pageIndex == null) | ||
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 job to check the sad path |
||
{ | ||
pageIndex = 1; | ||
return Ok(await _parkingLotsService.GetOnePageAsync((int)pageIndex)); | ||
} | ||
else | ||
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: else can be removed, since there is no other branch |
||
{ | ||
return Ok(await _parkingLotsService.GetOnePageAsync((int)pageIndex)); | ||
} | ||
} | ||
|
||
[HttpGet("{id}")] | ||
public async Task<ActionResult> GetParkingLotByIdAsync(string id) | ||
{ | ||
var parkingLot = await _parkingLotsService.GetByIdAsync(id); | ||
if (parkingLot == null) | ||
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: avoid return null from method, since it's hard to understand the meaning |
||
{ | ||
return NotFound(); | ||
} | ||
return Ok(parkingLot); | ||
} | ||
|
||
[HttpPut("{id}")] | ||
public async Task<ActionResult> GetParkingLotByIdAsync(string id, int capacity) | ||
{ | ||
var updatedParkingLot = await _parkingLotsService.UpdateParkingLotCapacityAsync(capacity, id); | ||
if (updatedParkingLot == null) | ||
{ | ||
return NotFound(); | ||
} | ||
return Ok(updatedParkingLot); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using ParkingLotApi.Models; | ||
|
||
namespace ParkingLotApi.Dtos; | ||
|
||
public class ParkingLotDto | ||
{ | ||
public string Name { get; set; } //ctrl+d自动向下复制一行 | ||
public int Capacity { get; set; } | ||
public string Location { get; set; } | ||
|
||
internal ParkingLot ToEntity() | ||
{ | ||
return new ParkingLot() | ||
{ | ||
Name = Name, | ||
Capacity = Capacity, | ||
Location = Location | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace ParkingLotApi.Exceptions | ||
{ | ||
public class InvalidCapacityException : Exception | ||
{ | ||
|
||
} | ||
} |
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 InvalidCapacityExceptionFilter : IActionFilter, IOrderedFilter | ||
{ | ||
int IOrderedFilter.Order => int.MaxValue - 10; | ||
|
||
void IActionFilter.OnActionExecuted(ActionExecutedContext context) //excute when controller method return | ||
{ | ||
if (context.Exception is InvalidCapacityException invalidCapacityException) | ||
{ | ||
context.Result = new BadRequestResult(); | ||
context.ExceptionHandled = true; | ||
} | ||
} | ||
|
||
void IActionFilter.OnActionExecuting(ActionExecutingContext context) //excute before controller method run | ||
{ | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
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,13 @@ | ||
using ParkingLotApi.Models; | ||
|
||
namespace ParkingLotApi.Repository | ||
{ | ||
public interface IParkingLotsRepository | ||
{ | ||
Task<ParkingLot> CreateParkingLot(ParkingLot parkingLot); | ||
Task DeleteParkingLot(string ParkingLotId); | ||
Task<List<ParkingLot>> GetAllParkingLots(); | ||
Task<ParkingLot> GetById(string ParkingLotId); | ||
Task<ParkingLot> UpdateParkingLot(string ParkingLotId, ParkingLot updatedParkingLot); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using Microsoft.Extensions.Options; | ||
using MongoDB.Driver; | ||
using ParkingLotApi.Models; | ||
|
||
namespace ParkingLotApi.Repository | ||
{ | ||
public class ParkingLotsRepository : IParkingLotsRepository //alt+enter implement members in interface | ||
|
||
{ | ||
private readonly IMongoCollection<ParkingLot> _parkingLotCollection; //连mongodb数据库 | ||
|
||
public ParkingLotsRepository(IOptions<ParkingLotDatabaseSettings> parkingLotDatabaseSettings) | ||
{ | ||
var mongoClient = new MongoClient(parkingLotDatabaseSettings.Value.ConnectionString); //connections tring连接到数据库url | ||
var mongoDatabase = mongoClient.GetDatabase(parkingLotDatabaseSettings.Value.DatabaseName); //通过客户端连接相应数据库 | ||
|
||
_parkingLotCollection = mongoDatabase.GetCollection<ParkingLot>(parkingLotDatabaseSettings.Value.CollectionName); //用database取相应collection | ||
|
||
//从数据存储的地方获取collection | ||
} | ||
|
||
public async Task<ParkingLot> CreateParkingLot(ParkingLot parkingLot) //repo是最底层的,所以用parkinglot,Dto是外界和controller的对象 | ||
{ | ||
await _parkingLotCollection.InsertOneAsync(parkingLot); | ||
return await _parkingLotCollection.Find(a => a.Name == parkingLot.Name).FirstAsync(); //find created item by name | ||
} | ||
|
||
public async Task DeleteParkingLot(string ParkingLotId) //没有给return的值就不用return await | ||
{ | ||
await _parkingLotCollection.DeleteOneAsync(p => p.Id == ParkingLotId); | ||
} | ||
|
||
public async Task<List<ParkingLot>> GetAllParkingLots() | ||
{ | ||
return await _parkingLotCollection.Find(_ => true).ToListAsync(); | ||
} | ||
|
||
public async Task<ParkingLot> GetById(string ParkingLotId) | ||
{ | ||
return await _parkingLotCollection.Find(p => p.Id == ParkingLotId).FirstAsync(); | ||
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: use FirstOrDefaultAsync instead. |
||
} | ||
|
||
public async Task<ParkingLot> UpdateParkingLot(string ParkingLotId, ParkingLot updatedParkingLot) | ||
{ | ||
await _parkingLotCollection.ReplaceOneAsync(p => p.Id == ParkingLotId, updatedParkingLot); | ||
return await GetById(ParkingLotId); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using ParkingLotApi.Dtos; | ||
using ParkingLotApi.Exceptions; | ||
using ParkingLotApi.Models; | ||
using ParkingLotApi.Repository; | ||
|
||
namespace ParkingLotApi.Services | ||
{ | ||
public class ParkingLotsService | ||
{ | ||
private readonly IParkingLotsRepository parkingLotsRepository; | ||
public ParkingLotsService(IParkingLotsRepository parkingLotsRepository) | ||
{ | ||
this.parkingLotsRepository = parkingLotsRepository; | ||
} | ||
|
||
public async Task<ParkingLot> AddAsync(ParkingLotDto parkingLotDto) //Task<返回值的类型> | ||
{ | ||
if (parkingLotDto.Capacity < 10) | ||
{ | ||
throw new InvalidCapacityException(); | ||
} | ||
|
||
return await parkingLotsRepository.CreateParkingLot(parkingLotDto.ToEntity()); | ||
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: hold transfer to entity logic in DTO |
||
//用外界传进来的dto,return parkinglot给repo | ||
} | ||
|
||
public async Task DeleteAsync(string parkingLotId) | ||
{ | ||
await parkingLotsRepository.DeleteParkingLot(parkingLotId); | ||
} | ||
|
||
public async Task<List<ParkingLot>> GetOnePageAsync(int pageIndex) | ||
{ | ||
List<ParkingLot> allParkingLots = await parkingLotsRepository.GetAllParkingLots(); | ||
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: extract this variable to a constant |
||
int startIndex = (pageIndex - 1) * pageSize; | ||
return allParkingLots.Skip(startIndex).Take(pageSize).ToList(); | ||
} | ||
|
||
public async Task<ParkingLot> GetByIdAsync(string parkingLotId) | ||
{ | ||
return await parkingLotsRepository.GetById(parkingLotId); | ||
} | ||
|
||
public async Task<ParkingLot> UpdateParkingLotCapacityAsync(int capacity, string parkingLotId) | ||
{ | ||
if (capacity < 10) | ||
{ | ||
throw new InvalidCapacityException(); | ||
} | ||
|
||
var parkingLot = await parkingLotsRepository.GetById(parkingLotId); | ||
var updatedParkingLot = new ParkingLot() | ||
{ | ||
Capacity = capacity, | ||
Id = parkingLot.Id, | ||
Name = parkingLot.Name, | ||
Location = parkingLot.Location | ||
}; | ||
|
||
return await parkingLotsRepository.UpdateParkingLot(parkingLotId, updatedParkingLot); | ||
|
||
} | ||
|
||
} | ||
} |
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