From 9e38cfd25dbd69904b14a1222ccf26f90e31223a Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 14 May 2022 20:19:41 +0200 Subject: [PATCH] Add contact controller --- Controllers/ContactUsController.cs | 82 ++++++++++++++++++++++ Converters/Extensions.cs | 13 ++++ Dtos/ContactDto.cs | 14 ++++ Dtos/CreateContactDto.cs | 15 ++++ Models/Contact.cs | 13 ++++ Repositories/IContactRepository.cs | 20 ++++++ Repositories/MongoDBContactUsRepository.cs | 53 ++++++++++++++ Startup.cs | 1 + WeatherForecast.cs | 15 ---- appsettings.json | 2 +- 10 files changed, 212 insertions(+), 16 deletions(-) create mode 100644 Controllers/ContactUsController.cs create mode 100644 Dtos/ContactDto.cs create mode 100644 Dtos/CreateContactDto.cs create mode 100644 Models/Contact.cs create mode 100644 Repositories/IContactRepository.cs create mode 100644 Repositories/MongoDBContactUsRepository.cs delete mode 100644 WeatherForecast.cs diff --git a/Controllers/ContactUsController.cs b/Controllers/ContactUsController.cs new file mode 100644 index 0000000..460cc89 --- /dev/null +++ b/Controllers/ContactUsController.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Mvc; + +using weddingapi.Models; +using weddingapi.Repositories; +using weddingapi.Dtos; +using weddingapi.Converters; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Cors; + +namespace weddingapi.Controllers +{ + [ApiController] + [Route("contact")] + public class ContactUsController : ControllerBase + { + private readonly IContactRepository repository; + + public ContactUsController(IContactRepository repository) + { + this.repository = repository; + } + + // POST /contact + [HttpPost] + public async Task> CreateContactAsync(CreateContactDto contactDto) + { + Contact contact = new Contact() + { + Id = Guid.NewGuid(), + CreatedDate = DateTimeOffset.UtcNow, + From = contactDto.From, + Email = contactDto.Email, + Message = contactDto.Message, + }; + + await repository.CreateContactAsync(contact); + + return CreatedAtAction(nameof(GetContactAsync), new { id = contact.Id }, contact.AsDto()); + } + + // GET /contact/{id} + [HttpGet("{id}")] + public async Task> GetContactAsync(Guid id) + { + var contact = await repository.GetContactAsync(id); + + if(contact is null) + { + return NotFound(); + } + + return contact.AsDto(); + } + + // Delete /contact/{id} + [HttpDelete("{id}")] + public async Task DeleteContactAsync(Guid id) + { + var exisitingFamily = repository.GetContactAsync(id); + + if(exisitingFamily is null) + { + return NotFound(); + } + + await repository.DeleteContactAsync(id); + + return NoContent(); + } + + // GET /contacts + [HttpGet] + public async Task> GetContactsAsync() + { + var contacts = (await repository.GetContactsAsync()).Select(contact => contact.AsDto()); + return contacts; + } + } +} \ No newline at end of file diff --git a/Converters/Extensions.cs b/Converters/Extensions.cs index 0e41bf9..37d6181 100644 --- a/Converters/Extensions.cs +++ b/Converters/Extensions.cs @@ -28,6 +28,19 @@ namespace weddingapi.Converters Name = person.Name, }; } + + + public static ContactDto AsDto(this Contact contact) + { + return new ContactDto() + { + CreatedDate = contact.CreatedDate, + Email = contact.Email, + From = contact.From, + Id = contact.Id, + Message = contact.Message, + }; + } } } diff --git a/Dtos/ContactDto.cs b/Dtos/ContactDto.cs new file mode 100644 index 0000000..7938f49 --- /dev/null +++ b/Dtos/ContactDto.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; + +namespace weddingapi.Dtos +{ + public record ContactDto + { + public Guid Id { get; init; } + public string From { get; init; } + public string Email { get; init; } + public string Message { get; init; } + public DateTimeOffset CreatedDate { get; set; } + } +} \ No newline at end of file diff --git a/Dtos/CreateContactDto.cs b/Dtos/CreateContactDto.cs new file mode 100644 index 0000000..3071766 --- /dev/null +++ b/Dtos/CreateContactDto.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace weddingapi.Dtos +{ + public record CreateContactDto + { + [Required] + public string From { get; init; } + [Required] + public string Email { get; init; } + [Required] + public string Message { get; init; } + } +} \ No newline at end of file diff --git a/Models/Contact.cs b/Models/Contact.cs new file mode 100644 index 0000000..ce93349 --- /dev/null +++ b/Models/Contact.cs @@ -0,0 +1,13 @@ +using System; + +namespace weddingapi +{ + public record Contact + { + public Guid Id { get; init; } + public string From { get; init; } + public string Email { get; init; } + public string Message { get; init; } + public DateTimeOffset CreatedDate { get; set; } + } +} diff --git a/Repositories/IContactRepository.cs b/Repositories/IContactRepository.cs new file mode 100644 index 0000000..bc3cf7d --- /dev/null +++ b/Repositories/IContactRepository.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using weddingapi.Models; + +namespace weddingapi.Repositories +{ + public interface IContactRepository + { + Task GetContactAsync(Guid id); + + Task> GetContactsAsync(); + + Task CreateContactAsync(Contact family); + + Task UpdateContactAsync(Contact family); + + Task DeleteContactAsync(Guid id); + } +} \ No newline at end of file diff --git a/Repositories/MongoDBContactUsRepository.cs b/Repositories/MongoDBContactUsRepository.cs new file mode 100644 index 0000000..7a4d22f --- /dev/null +++ b/Repositories/MongoDBContactUsRepository.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using MongoDB.Bson; +using MongoDB.Driver; +using weddingapi.Models; + +namespace weddingapi.Repositories +{ + public class MongoDBContactUsRepository : IContactRepository + { + private const string databaseName = "wedding"; + private const string collectionName = "contacts"; + private readonly IMongoCollection familyCollection; + private readonly FilterDefinitionBuilder filterBuilder = Builders.Filter; + + public MongoDBContactUsRepository(IMongoClient mongoClient) + { + IMongoDatabase database = mongoClient.GetDatabase(databaseName); + familyCollection = database.GetCollection(collectionName); + } + + public async Task CreateContactAsync(Contact contact) + { + await familyCollection.InsertOneAsync(contact); + } + + public async Task DeleteContactAsync(Guid id) + { + var filter = filterBuilder.Eq(contact => contact.Id, id); + await familyCollection.DeleteOneAsync(filter); + } + + public async Task> GetContactsAsync() + { + var res = await familyCollection.FindAsync(new BsonDocument()); + return await res.ToListAsync(); + } + + public async Task GetContactAsync(Guid id) + { + var filter = filterBuilder.Eq(contact => contact.Id, id); + var res = await familyCollection.FindAsync(filter); + return await res.SingleOrDefaultAsync(); + } + + public async Task UpdateContactAsync(Contact contact) + { + var filter = filterBuilder.Eq(exisitingContact => exisitingContact.Id, contact.Id); + await familyCollection.ReplaceOneAsync(filter, contact); + } + } +} \ No newline at end of file diff --git a/Startup.cs b/Startup.cs index 3a3f1ba..7588a88 100644 --- a/Startup.cs +++ b/Startup.cs @@ -45,6 +45,7 @@ namespace weddingapi }); services.AddSingleton(); + services.AddSingleton(); services.AddControllers(options => { options.SuppressAsyncSuffixInActionNames = false; }); diff --git a/WeatherForecast.cs b/WeatherForecast.cs deleted file mode 100644 index d139d82..0000000 --- a/WeatherForecast.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace weddingapi -{ - public class WeatherForecast - { - public DateTime Date { get; set; } - - public int TemperatureC { get; set; } - - public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); - - public string Summary { get; set; } - } -} diff --git a/appsettings.json b/appsettings.json index a36f796..395a3c4 100644 --- a/appsettings.json +++ b/appsettings.json @@ -8,7 +8,7 @@ }, "AllowedHosts": "*", "MongoDbConfig": { - "Host": "truenas", + "Host": "192.168.2.107", "Port": "27017" } }