From 3eae2aa8f30631b4e617f15aa1c297e0e7dd8f97 Mon Sep 17 00:00:00 2001 From: Colin Wu <85907102+ColinWu0403@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:14:57 -0400 Subject: [PATCH] Initial Code --- .dockerignore | 25 +++++++ .gitignore | 39 +++++++++++ Controllers/BuildingController.cs | 113 ++++++++++++++++++++++++++++++ Controllers/MyController.cs | 15 ++++ Dockerfile | 20 ++++++ Entities/Building.cs | 18 +++++ Program.cs | 42 +++++++++++ Properties/launchSettings.json | 31 ++++++++ README.md | 3 + Services/MongoDbService.cs | 32 +++++++++ SimpleWebAppReact.csproj | 29 ++++++++ Startup.cs | 60 ++++++++++++++++ appsettings.Development.json | 8 +++ appsettings.json | 13 ++++ 14 files changed, 448 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Controllers/BuildingController.cs create mode 100644 Controllers/MyController.cs create mode 100644 Dockerfile create mode 100644 Entities/Building.cs create mode 100644 Program.cs create mode 100644 Properties/launchSettings.json create mode 100644 README.md create mode 100644 Services/MongoDbService.cs create mode 100644 SimpleWebAppReact.csproj create mode 100644 Startup.cs create mode 100644 appsettings.Development.json create mode 100644 appsettings.json diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e6b1832 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* +.metro-health-check* + +# Static +node_modules +dist +dist-ssr +*.local +wwwroot +npm-debug.* + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.env +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision +*.orig.* +.expo/ +obj +bin +web-build/ \ No newline at end of file diff --git a/Controllers/BuildingController.cs b/Controllers/BuildingController.cs new file mode 100644 index 0000000..1ff8bf7 --- /dev/null +++ b/Controllers/BuildingController.cs @@ -0,0 +1,113 @@ +using Microsoft.AspNetCore.Mvc; +using SimpleWebAppReact.Entities; +using Microsoft.Extensions.Logging; +using MongoDB.Driver; +using SimpleWebAppReact.Services; + +namespace SimpleWebAppReact.Controllers +{ + /// + /// Defines endpoints for operations relating the Building table + /// + [ApiController] + [Route("api/[controller]")] + public class BuildingController : ControllerBase + { + private readonly ILogger _logger; + private readonly IMongoCollection? _buildings; + + public BuildingController(ILogger logger, MongoDbService mongoDbService) + { + _logger = logger; + _buildings = mongoDbService.Database?.GetCollection("building"); + } + + /// + /// gets buildings, with optional query parameters + /// + /// + /// + /// + [HttpGet] + public async Task> Get([FromQuery] string? name = null, [FromQuery] string? address = null) + { + // Build the filter using a filter builder + var filterBuilder = Builders.Filter; + var filter = FilterDefinition.Empty; + + // Apply the name filter if the parameter is provided + if (!string.IsNullOrEmpty(name)) + { + filter &= filterBuilder.Eq(b => b.Name, name); + } + + // Apply the address filter if the parameter is provided + if (!string.IsNullOrEmpty(address)) + { + filter &= filterBuilder.Eq(b => b.Address, address); + } + + // Fetch the buildings from the database using the filter + return await _buildings.Find(filter).ToListAsync(); + } + + /// + /// gets specific building with id + /// + /// + /// + [HttpGet("{id}")] + public async Task> GetById(string id) + { + // Simple validation to check if the ID is not null + if (string.IsNullOrEmpty(id)) + { + return BadRequest("Invalid ID format."); + } + + var filter = Builders.Filter.Eq(x => x.Id, id); + var building = _buildings.Find(filter).FirstOrDefault(); + return building is not null ? Ok(building) : NotFound(); + } + + /// + /// adds building entry to table + /// + /// + /// + [HttpPost] + public async Task Post(Building building) + { + await _buildings.InsertOneAsync(building); + return CreatedAtAction(nameof(GetById), new { id = building.Id }, building); + + } + + /// + /// updates a building entry + /// + /// + /// + [HttpPut] + public async Task Update(Building building) + { + var filter = Builders.Filter.Eq(x => x.Id, building.Id); + await _buildings.ReplaceOneAsync(filter, building); + return Ok(); + } + + /// + /// deletes a building entry + /// + /// + /// + [HttpDelete("{id}")] + public async Task Delete(string id) + { + var filter = Builders.Filter.Eq(x => x.Id, id); + await _buildings.DeleteOneAsync(filter); + return Ok(); + } + } +} + diff --git a/Controllers/MyController.cs b/Controllers/MyController.cs new file mode 100644 index 0000000..b18f93f --- /dev/null +++ b/Controllers/MyController.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Mvc; + +namespace SimpleWebAppReact.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class MyController : ControllerBase + { + [HttpGet("message")] // Define the route for this action + public IActionResult GetMessage() + { + return Ok(new { message = "Hello from ASP.NET Core!" }); + } + } +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e76b08f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["SimpleWebAppReact.csproj", "./"] +RUN dotnet restore "SimpleWebAppReact.csproj" +COPY . . +WORKDIR "/src/" +RUN dotnet build "SimpleWebAppReact.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "SimpleWebAppReact.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "SimpleWebAppReact.dll"] diff --git a/Entities/Building.cs b/Entities/Building.cs new file mode 100644 index 0000000..6627f8f --- /dev/null +++ b/Entities/Building.cs @@ -0,0 +1,18 @@ +namespace SimpleWebAppReact.Entities; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +/// +/// Class structure matches 1-1 with Building Table in database +/// +public class Building +{ + [BsonId] + [BsonElement("_id"), BsonRepresentation(BsonType.ObjectId)] + public string? Id { get; set; } + + [BsonElement("name"), BsonRepresentation(BsonType.String)] + public string? Name { get; set; } + + [BsonElement("address"), BsonRepresentation(BsonType.String)] + public string? Address { get; set; } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..4b111f2 --- /dev/null +++ b/Program.cs @@ -0,0 +1,42 @@ +using System.Diagnostics; +using SimpleWebAppReact.Services; + +var builder = WebApplication.CreateBuilder(args); + +// Add logging configuration +builder.Logging.AddConsole(); // Enable console logging + +// Add services to the container. +builder.Services.AddControllers(); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Services.AddSingleton(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseHsts(); +} + +// Configure logging +var logger = app.Services.GetRequiredService>(); +logger.LogInformation("Application started."); + +app.UseHttpsRedirection(); +app.UseStaticFiles(); +app.UseRouting(); + +app.UseCors("AllowAll"); // Enable CORS + +app.UseEndpoints(endpoints => +{ + endpoints.MapControllers(); + endpoints.MapFallbackToFile("/index.html"); // This will serve index.html for any routes not handled by the controller +}); + + +app.UseSwagger(); +app.UseSwaggerUI(); +app.Run(); diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..d683b9a --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:58527", + "sslPort": 44354 + } + }, + "profiles": { + "SimpleWebAppReact": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://0.0.0.0:5128", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..b7518f3 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Housing Backend + +Temp name diff --git a/Services/MongoDbService.cs b/Services/MongoDbService.cs new file mode 100644 index 0000000..0f12ed7 --- /dev/null +++ b/Services/MongoDbService.cs @@ -0,0 +1,32 @@ +using MongoDB.Driver; + +namespace SimpleWebAppReact.Services; + +/// +/// MongoDB Service +/// +public class MongoDbService +{ + private readonly IConfiguration _configuration; + private readonly IMongoDatabase? _database; + + /// + /// constructor connects to database + /// + /// + public MongoDbService(IConfiguration configuration) + { + _configuration = configuration; + + var connectionString = _configuration.GetConnectionString("DbConnection"); + var databaseName = _configuration.GetConnectionString("DatabaseName"); + Console.WriteLine("connection information:"); + Console.WriteLine(connectionString); + Console.WriteLine(databaseName); + var mongoUrl = MongoUrl.Create(connectionString); + var mongoClient = new MongoClient(mongoUrl); + _database = mongoClient.GetDatabase(databaseName); + } + + public IMongoDatabase? Database => _database; +} \ No newline at end of file diff --git a/SimpleWebAppReact.csproj b/SimpleWebAppReact.csproj new file mode 100644 index 0000000..55cfe95 --- /dev/null +++ b/SimpleWebAppReact.csproj @@ -0,0 +1,29 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + <_ContentIncludedByDefault Remove="ClientApp\app.json" /> + <_ContentIncludedByDefault Remove="ClientApp\package-lock.json" /> + <_ContentIncludedByDefault Remove="ClientApp\package.json" /> + <_ContentIncludedByDefault Remove="ClientApp\tsconfig.json" /> + + + diff --git a/Startup.cs b/Startup.cs new file mode 100644 index 0000000..055b3c1 --- /dev/null +++ b/Startup.cs @@ -0,0 +1,60 @@ +namespace SimpleWebAppReact; + +/// +/// runs startup commands, builds front end, CORS +/// +public class Startup +{ + /// + /// start up + /// + /// + public Startup(IConfiguration configuration) + { + } + + public void ConfigureServices(IServiceCollection services) + { + services.AddControllers(); + + // Configure CORS to allow requests from React Native frontend + services.AddCors(options => + { + options.AddPolicy("AllowAll", builder => + { + builder.AllowAnyOrigin() + .AllowAnyMethod() + .AllowAnyHeader(); + }); + }); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Error"); + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseRouting(); + + app.UseStaticFiles(); + + // Enable CORS + app.UseCors("AllowAll"); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + endpoints.MapFallbackToFile("/index.html"); + }); + } +} \ No newline at end of file diff --git a/appsettings.Development.json b/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..3a50bfa --- /dev/null +++ b/appsettings.json @@ -0,0 +1,13 @@ +{ + "ConnectionStrings": { + "DbConnection": "mongodb://liu3447:password@dev.sigapp.club:8222", + "DatabaseName": "test" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}