diff --git a/Assignment3.sln b/Assignment3.sln
new file mode 100644
index 0000000..64be85a
--- /dev/null
+++ b/Assignment3.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.12.35707.178 d17.12
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Assignment3", "Assignment3\Assignment3.csproj", "{DEF9F47D-4197-4225-92F1-4373FF2F4185}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DEF9F47D-4197-4225-92F1-4373FF2F4185}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DEF9F47D-4197-4225-92F1-4373FF2F4185}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DEF9F47D-4197-4225-92F1-4373FF2F4185}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DEF9F47D-4197-4225-92F1-4373FF2F4185}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Assignment3/Assignment3.csproj b/Assignment3/Assignment3.csproj
new file mode 100644
index 0000000..f2df489
--- /dev/null
+++ b/Assignment3/Assignment3.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
diff --git a/Assignment3/Controllers/ImmunizationsController.cs b/Assignment3/Controllers/ImmunizationsController.cs
new file mode 100644
index 0000000..fe7d9b0
--- /dev/null
+++ b/Assignment3/Controllers/ImmunizationsController.cs
@@ -0,0 +1,222 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Assignment3.Data;
+using Assignment3.Models;
+using System.Xml.Linq;
+
+namespace Assignment3.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class ImmunizationsController : ControllerBase
+ {
+ private readonly Assignment3Context _context;
+
+ public ImmunizationsController(Assignment3Context context)
+ {
+ _context = context;
+ }
+
+ // GET: api/Immunizations
+ [HttpGet]
+ public async Task>> GetImmunization()
+ {
+ if (_context.Immunization == null)
+ {
+ return NotFound();
+ }
+ return await _context.Immunization.ToListAsync();
+ }
+
+ // GET: api/Immunizations/5
+ [HttpGet("{id}")]
+ public async Task> GetImmunization(Guid id)
+ {
+ if (_context.Immunization == null)
+ {
+ return NotFound();
+ }
+ var immunization = await _context.Immunization.FindAsync(id);
+
+ if (immunization == null)
+ {
+ return NotFound();
+ }
+
+ return immunization;
+ }
+
+ // PUT: api/Immunizations/5
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPut("{id}")]
+ public async Task PutImmunization(Guid id, Immunization immunization)
+ {
+ if (id != immunization.Id)
+ {
+ return BadRequest();
+ }
+
+ _context.Entry(immunization).State = EntityState.Modified;
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!ImmunizationExists(id))
+ {
+ return NotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return NoContent();
+ }
+
+ // POST: api/Immunizations
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPost]
+ public async Task> PostImmunization(Immunization immunization)
+ {
+ if (_context.Immunization == null)
+ {
+ return Problem("Entity set 'Assignment3Context.Immunization' is null.");
+ }
+ _context.Immunization.Add(immunization);
+ await _context.SaveChangesAsync();
+
+ return CreatedAtAction("GetImmunization", new { id = immunization.Id }, immunization);
+ }
+
+ // DELETE: api/Immunizations/5
+ [HttpDelete("{id}")]
+ public async Task DeleteImmunization(Guid id)
+ {
+ if (_context.Immunization == null)
+ {
+ return NotFound();
+ }
+ var immunization = await _context.Immunization.FindAsync(id);
+ if (immunization == null)
+ {
+ return NotFound();
+ }
+
+ _context.Immunization.Remove(immunization);
+ await _context.SaveChangesAsync();
+
+ return NoContent();
+ }
+
+ private bool ImmunizationExists(Guid id)
+ {
+ return (_context.Immunization?.Any(e => e.Id == id)).GetValueOrDefault();
+ }
+
+
+ [HttpGet("creationTime={value}")]
+ public async Task> GetcreationTime(DateTimeOffset time)
+ {
+ if (_context.Immunization == null)
+ {
+ return NotFound();
+ }
+
+ var immunization = await _context.Immunization
+ .FirstOrDefaultAsync(i => i.CreationTime == time);
+
+ if (immunization == null)
+ {
+ return NotFound();
+ }
+
+ return immunization;
+
+
+
+
+ }
+
+
+ //Fixed to search the no primary column
+ // also change url name to match function input of name
+ // does it need to return just one or many if it applies to many for searching
+ [HttpGet("officialName={name}")]
+ public async Task> GetofficialName(String name)
+ {
+ if (_context.Immunization == null)
+ {
+ return NotFound();
+ }
+ var immunizations = await _context.Immunization
+ .FirstOrDefaultAsync(i => i.OfficialName == name);
+
+ if (immunizations == null)
+ {
+ return NotFound();
+ }
+
+ return Ok(immunizations);
+
+ }
+
+
+
+ [HttpGet("tradeName={value}")]
+ public async Task> GettradeName(String name)
+ {
+ if (_context.Immunization == null)
+ {
+ return NotFound();
+ }
+ var immunization = await _context.Immunization
+ .FirstOrDefaultAsync(i => i.TradeName == name);
+
+ if (immunization == null)
+ {
+ return NotFound();
+ }
+
+ return immunization;
+
+
+
+ }
+
+
+
+ [HttpGet("lotNumber={value}")]
+ public async Task> GetlotNumber(String number)
+ {
+ if (_context.Immunization == null)
+ {
+ return NotFound();
+ }
+ var immunization = await _context.Immunization
+ .FirstOrDefaultAsync(i => i.LotNumber == number);
+
+ if (immunization == null)
+ {
+ return NotFound();
+ }
+
+ return immunization;
+
+
+
+
+ }
+
+
+
+ }
+}
diff --git a/Assignment3/Controllers/OrganizationsController.cs b/Assignment3/Controllers/OrganizationsController.cs
new file mode 100644
index 0000000..1d77aff
--- /dev/null
+++ b/Assignment3/Controllers/OrganizationsController.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Assignment3.Data;
+using Assignment3.Models;
+using System.ComponentModel.DataAnnotations;
+using System.Xml.Linq;
+
+namespace Assignment3.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class OrganizationsController : ControllerBase
+ {
+ private readonly Assignment3Context _context;
+
+ public OrganizationsController(Assignment3Context context)
+ {
+ _context = context;
+ }
+
+ // GET: api/Organizations
+ [HttpGet]
+ public async Task>> GetOrganization()
+ {
+ if (_context.Organization == null)
+ {
+ return NotFound();
+ }
+ return await _context.Organization.ToListAsync();
+ }
+
+ // GET: api/Organizations/5
+ [HttpGet("{id}")]
+ public async Task> GetOrganization(Guid id)
+ {
+ if (_context.Organization == null)
+ {
+ return NotFound();
+ }
+ var organization = await _context.Organization.FindAsync(id);
+
+ if (organization == null)
+ {
+ return NotFound();
+ }
+
+ return organization;
+ }
+
+ // PUT: api/Organizations/5
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPut("{id}")]
+ public async Task PutOrganization(Guid id, Organization organization)
+ {
+ if (id != organization.Id)
+ {
+ return BadRequest();
+ }
+
+ _context.Entry(organization).State = EntityState.Modified;
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!OrganizationExists(id))
+ {
+ return NotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return NoContent();
+ }
+
+ // POST: api/Organizations
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPost]
+ public async Task> PostOrganization(Organization organization)
+ {
+ var validationResults = new List();
+ bool isValid = Validator.TryValidateObject(organization, new ValidationContext(organization), validationResults, true);
+
+ if (_context.Organization == null)
+ {
+ return Problem("Entity set 'Assignment3Context.Organization' is null.");
+ }
+ _context.Organization.Add(organization);
+ await _context.SaveChangesAsync();
+
+ return CreatedAtAction("GetOrganization", new { id = organization.Id }, organization);
+ }
+
+ // DELETE: api/Organizations/5
+ [HttpDelete("{id}")]
+ public async Task DeleteOrganization(Guid id)
+ {
+ if (_context.Organization == null)
+ {
+ return NotFound();
+ }
+ var organization = await _context.Organization.FindAsync(id);
+ if (organization == null)
+ {
+ return NotFound();
+ }
+
+ _context.Organization.Remove(organization);
+ await _context.SaveChangesAsync();
+
+ return NoContent();
+ }
+
+ [HttpGet("name={value}")]
+ public async Task> GetOrganizationName(string name)
+ {
+ if (_context.Organization == null)
+ {
+ return NotFound();
+ }
+ var organization = await _context.Organization.FirstOrDefaultAsync(i => i.Name == name);
+
+ if (organization == null)
+ {
+ return NotFound();
+ }
+
+ return organization;
+ }
+
+
+
+
+ [HttpGet("type={value}")]
+ public async Task> GetOrganizationType(string type)
+ {
+ if (_context.Organization == null)
+ {
+ return NotFound();
+ }
+ var organization = await _context.Organization.FirstOrDefaultAsync(i => i.Type == type); ;
+
+ if (organization == null)
+ {
+ return NotFound();
+ }
+
+ return organization;
+ }
+
+ private bool OrganizationExists(Guid id)
+ {
+ return (_context.Organization?.Any(e => e.Id == id)).GetValueOrDefault();
+ }
+ }
+}
diff --git a/Assignment3/Controllers/PatientsController.cs b/Assignment3/Controllers/PatientsController.cs
new file mode 100644
index 0000000..4b35920
--- /dev/null
+++ b/Assignment3/Controllers/PatientsController.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Assignment3.Data;
+using Assignment3.Models;
+using System.Xml.Linq;
+
+namespace Assignment3.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class PatientsController : ControllerBase
+ {
+ private readonly Assignment3Context _context;
+
+ public PatientsController(Assignment3Context context)
+ {
+ _context = context;
+ }
+
+ // GET: api/Patients
+ [HttpGet]
+ public async Task>> GetPatient()
+ {
+ if (_context.Patient == null)
+ {
+ return NotFound();
+ }
+ return await _context.Patient.ToListAsync();
+ }
+
+ // GET: api/Patients/5
+ [HttpGet("{id}")]
+ public async Task> GetPatient(Guid id)
+ {
+ if (_context.Patient == null)
+ {
+ return NotFound();
+ }
+ var patient = await _context.Patient.FindAsync(id);
+ if (patient == null)
+ {
+ return NotFound();
+ }
+
+ return patient;
+ }
+
+ // PUT: api/Patients/5
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPut("{id}")]
+ public async Task PutPatient(Guid id, Patient patient)
+ {
+ if (id != patient.Id)
+ {
+ return BadRequest();
+ }
+
+ _context.Entry(patient).State = EntityState.Modified;
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!PatientExists(id))
+ {
+ return NotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return NoContent();
+ }
+
+ // POST: api/Patients
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPost]
+ public async Task> PostPatient(Patient patient)
+ {
+ if (_context.Patient == null)
+ {
+ return Problem("Entity set 'Assignment3Context.Patient' is null.");
+ }
+ _context.Patient.Add(patient);
+ await _context.SaveChangesAsync();
+
+ return CreatedAtAction("GetPatient", new { id = patient.Id }, patient);
+ }
+
+ // DELETE: api/Patients/5
+ [HttpDelete("{id}")]
+ public async Task DeletePatient(Guid id)
+ {
+ if (_context.Patient == null)
+ {
+ return NotFound();
+ }
+ var patient = await _context.Patient.FindAsync(id);
+ if (patient == null)
+ {
+ return NotFound();
+ }
+
+ _context.Patient.Remove(patient);
+ await _context.SaveChangesAsync();
+
+ return NoContent();
+ }
+
+
+ [HttpGet("firstName={value}")]
+ public async Task> GetPatientFirstName(string firstName)
+ {
+ if (_context.Patient == null)
+ {
+ return NotFound();
+ }
+ var patient = await _context.Patient.FirstOrDefaultAsync(i => i.FirstName == firstName);
+
+ if (patient == null)
+ {
+ return NotFound();
+ }
+
+ return patient;
+ }
+
+
+
+ [HttpGet("lastName={value}")]
+ public async Task> GetPatientLastName(string lastname)
+ {
+ if (_context.Patient == null)
+ {
+ return NotFound();
+ }
+ var patient = await _context.Patient.FirstOrDefaultAsync(i => i.LastName == lastname);
+
+ if (patient == null)
+ {
+ return NotFound();
+ }
+
+ return patient;
+ }
+
+
+
+
+
+
+
+
+ [HttpGet("dateOfBirth={value}")]
+ public async Task> GetPatientdateOfBirth(DateTimeOffset date)
+ {
+ if (_context.Patient == null)
+ {
+ return NotFound();
+ }
+ var patient = await _context.Patient.FirstOrDefaultAsync(i => i.DateOfBirth == date);
+
+
+
+ if (patient == null)
+ {
+ return NotFound();
+ }
+
+ return patient;
+ }
+
+
+
+
+
+
+ private bool PatientExists(Guid id)
+ {
+ return (_context.Patient?.Any(e => e.Id == id)).GetValueOrDefault();
+ }
+
+
+ }
+
+}
diff --git a/Assignment3/Controllers/ProvidersController.cs b/Assignment3/Controllers/ProvidersController.cs
new file mode 100644
index 0000000..98a243f
--- /dev/null
+++ b/Assignment3/Controllers/ProvidersController.cs
@@ -0,0 +1,189 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Assignment3.Data;
+using Assignment3.Models;
+using NuGet.Packaging.Signing;
+
+namespace Assignment3.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class ProvidersController : ControllerBase
+ {
+ private readonly Assignment3Context _context;
+
+ public ProvidersController(Assignment3Context context)
+ {
+ _context = context;
+ }
+
+ // GET: api/Providers
+ [HttpGet]
+ public async Task>> GetProvider()
+ {
+ if (_context.Provider == null)
+ {
+ return NotFound();
+ }
+ return await _context.Provider.ToListAsync();
+ }
+
+ // GET: api/Providers/5
+ [HttpGet("{id}")]
+ public async Task> GetProvider(Guid id)
+ {
+ if (_context.Provider == null)
+ {
+ return NotFound();
+ }
+ var provider = await _context.Provider.FindAsync(id);
+
+ if (provider == null)
+ {
+ return NotFound();
+ }
+
+ return provider;
+ }
+
+ // PUT: api/Providers/5
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPut("{id}")]
+ public async Task PutProvider(Guid id, Provider provider)
+ {
+ if (id != provider.Id)
+ {
+ return BadRequest();
+ }
+
+ _context.Entry(provider).State = EntityState.Modified;
+
+ try
+ {
+ await _context.SaveChangesAsync();
+ }
+ catch (DbUpdateConcurrencyException)
+ {
+ if (!ProviderExists(id))
+ {
+ return NotFound();
+ }
+ else
+ {
+ throw;
+ }
+ }
+
+ return NoContent();
+ }
+
+ // POST: api/Providers
+ // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
+ [HttpPost]
+ public async Task> PostProvider(Provider provider)
+ {
+ if (_context.Provider == null)
+ {
+ return Problem("Entity set 'Assignment3Context.Provider' is null.");
+ }
+ _context.Provider.Add(provider);
+ await _context.SaveChangesAsync();
+
+ return CreatedAtAction("GetProvider", new { id = provider.Id }, provider);
+ }
+
+ // DELETE: api/Providers/5
+ [HttpDelete("{id}")]
+ public async Task DeleteProvider(Guid id)
+ {
+ if (_context.Provider == null)
+ {
+ return NotFound();
+ }
+ var provider = await _context.Provider.FindAsync(id);
+ if (provider == null)
+ {
+ return NotFound();
+ }
+
+ _context.Provider.Remove(provider);
+ await _context.SaveChangesAsync();
+
+ return NoContent();
+ }
+
+
+ [HttpGet("firstName={value}")]
+ public async Task> GetProviderFirstName(string firstName)
+ {
+ if (_context.Provider == null)
+ {
+ return NotFound();
+ }
+ var provider = await _context.Provider.FirstOrDefaultAsync(i => i.FirstName == firstName);
+
+ if (provider == null)
+ {
+ return NotFound();
+
+
+ }
+
+ return provider;
+ }
+
+ [HttpGet("lastName={value}")]
+ public async Task> GetProviderLastName(string lastname)
+ {
+ if (_context.Provider == null)
+ {
+ return NotFound();
+ }
+ var provider = await _context.Provider.FirstOrDefaultAsync(i => i.LastName == lastname);
+
+ if (provider == null)
+ {
+ return NotFound();
+
+
+ }
+
+ return provider;
+ }
+
+
+ [HttpGet("licenseNumber={value}")]
+ public async Task> GetProviderlicenseNumber(long number)
+ {
+ if (_context.Provider == null)
+ {
+ return NotFound();
+ }
+ var provider = await _context.Provider.FirstOrDefaultAsync(i => i.LicenseNumber == number);
+
+ if (provider == null)
+ {
+ return NotFound();
+
+
+ }
+
+ return provider;
+ }
+
+
+
+
+
+
+ private bool ProviderExists(Guid id)
+ {
+ return (_context.Provider?.Any(e => e.Id == id)).GetValueOrDefault();
+ }
+ }
+}
diff --git a/Assignment3/Data/Assignment3Context.cs b/Assignment3/Data/Assignment3Context.cs
new file mode 100644
index 0000000..dd5913b
--- /dev/null
+++ b/Assignment3/Data/Assignment3Context.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Assignment3.Models;
+
+namespace Assignment3.Data
+{
+ public class Assignment3Context : DbContext
+ {
+ public Assignment3Context (DbContextOptions options)
+ : base(options)
+ {
+ }
+
+ public DbSet Immunization { get; set; } = default!;
+
+ public DbSet? Organization { get; set; }
+
+ public DbSet? Patient { get; set; }
+
+ public DbSet? Provider { get; set; }
+ public DbSet? Error { get; set; }
+ }
+}
diff --git a/Assignment3/Middleware/ErrorlogMiddleware.cs b/Assignment3/Middleware/ErrorlogMiddleware.cs
new file mode 100644
index 0000000..4f6b670
--- /dev/null
+++ b/Assignment3/Middleware/ErrorlogMiddleware.cs
@@ -0,0 +1,52 @@
+using Assignment3.Models;
+using Microsoft.AspNetCore.Mvc;
+using System.Text.Json;
+
+namespace Assignment3.Middleware
+{
+ public class ErrorlogMiddleware
+ {
+ private readonly ILogger _logger;
+ private readonly RequestDelegate next;
+ public ErrorlogMiddleware(RequestDelegate next, ILogger logger)
+ {
+ this.next = next;
+ this._logger = logger;
+ }
+
+ public async Task Invoke(HttpContext context)
+ {
+ var originalBodyStream = context.Response.Body;
+
+ using var responseBody = new MemoryStream();
+ context.Response.Body = responseBody;
+
+ await this.next(context);
+
+ context.Response.Body.Seek(0, SeekOrigin.Begin);
+ var responseText = await new StreamReader(context.Response.Body).ReadToEndAsync();
+
+ if (context.Response.StatusCode != 200)
+ {
+ Error err = new Error();
+ err.status = context.Response.StatusCode;
+ err.Message = "This needs to be populated...";
+
+ Console.WriteLine("Error Detected, writing to Database.");
+ var errors = context.Items["Error"] as List;
+ if (errors != null)
+ {
+ errors.Add(err);
+ }
+ else
+ {
+ context.Items["Errors"] = new List { err };
+ }
+ }
+
+ context.Response.Body.Seek(0, SeekOrigin.Begin);
+ await responseBody.CopyToAsync(originalBodyStream);
+ context.Response.Body = originalBodyStream;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assignment3/Migrations/20250310162707_init.Designer.cs b/Assignment3/Migrations/20250310162707_init.Designer.cs
new file mode 100644
index 0000000..f24c175
--- /dev/null
+++ b/Assignment3/Migrations/20250310162707_init.Designer.cs
@@ -0,0 +1,148 @@
+//
+using System;
+using Assignment3.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Assignment3.Migrations
+{
+ [DbContext(typeof(Assignment3Context))]
+ [Migration("20250310162707_init")]
+ partial class init
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.35")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
+
+ modelBuilder.Entity("Assignment3.Models.Immunization", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("LotNumber")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("OfficialName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("TradeName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("UpdatedTime")
+ .HasColumnType("datetimeoffset");
+
+ b.HasKey("Id");
+
+ b.ToTable("Immunization");
+ });
+
+ modelBuilder.Entity("Assignment3.Models.Organization", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Address")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Organization");
+ });
+
+ modelBuilder.Entity("Assignment3.Models.Patient", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("DateOfBirth")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Patient");
+ });
+
+ modelBuilder.Entity("Assignment3.Models.Provider", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Address")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LicenseNumber")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("Provider");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Assignment3/Migrations/20250310162707_init.cs b/Assignment3/Migrations/20250310162707_init.cs
new file mode 100644
index 0000000..0e8bc96
--- /dev/null
+++ b/Assignment3/Migrations/20250310162707_init.cs
@@ -0,0 +1,103 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Assignment3.Migrations
+{
+ public partial class init : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Immunization",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ CreationTime = table.Column(type: "datetimeoffset", nullable: false),
+ OfficialName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ TradeName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true),
+ LotNumber = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false),
+ ExpirationDate = table.Column(type: "datetimeoffset", nullable: false),
+ UpdatedTime = table.Column(type: "datetimeoffset", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Immunization", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Organization",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ CreationTime = table.Column(type: "datetimeoffset", nullable: false),
+ Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false),
+ Type = table.Column(type: "nvarchar(max)", nullable: false),
+ Address = table.Column(type: "nvarchar(max)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Organization", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Patient",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ CreationTime = table.Column(type: "datetimeoffset", nullable: false),
+ FirstName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ LastName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ DateOfBirth = table.Column(type: "datetimeoffset", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Patient", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Provider",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ CreationTime = table.Column(type: "datetimeoffset", nullable: false),
+ FirstName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ LastName = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false),
+ LicenseNumber = table.Column(type: "bigint", nullable: false),
+ Address = table.Column(type: "nvarchar(max)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Provider", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Error",
+ columns: table => new
+ {
+ Id = table.Column(type: "uniqueidentifier", nullable: false),
+ StatusCode = table.Column(type: "int", nullable: false),
+ Message = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false)
+ });
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "Immunization");
+
+ migrationBuilder.DropTable(
+ name: "Organization");
+
+ migrationBuilder.DropTable(
+ name: "Patient");
+
+ migrationBuilder.DropTable(
+ name: "Provider");
+
+ migrationBuilder.DropTable(
+ name: "Error");
+ }
+ }
+}
diff --git a/Assignment3/Migrations/Assignment3ContextModelSnapshot.cs b/Assignment3/Migrations/Assignment3ContextModelSnapshot.cs
new file mode 100644
index 0000000..fd1bc5b
--- /dev/null
+++ b/Assignment3/Migrations/Assignment3ContextModelSnapshot.cs
@@ -0,0 +1,146 @@
+//
+using System;
+using Assignment3.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Assignment3.Migrations
+{
+ [DbContext(typeof(Assignment3Context))]
+ partial class Assignment3ContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.35")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
+
+ modelBuilder.Entity("Assignment3.Models.Immunization", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("LotNumber")
+ .IsRequired()
+ .HasMaxLength(255)
+ .HasColumnType("nvarchar(255)");
+
+ b.Property("OfficialName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("TradeName")
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("UpdatedTime")
+ .HasColumnType("datetimeoffset");
+
+ b.HasKey("Id");
+
+ b.ToTable("Immunization");
+ });
+
+ modelBuilder.Entity("Assignment3.Models.Organization", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Address")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("nvarchar(256)");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Organization");
+ });
+
+ modelBuilder.Entity("Assignment3.Models.Patient", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("DateOfBirth")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Patient");
+ });
+
+ modelBuilder.Entity("Assignment3.Models.Provider", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Address")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("CreationTime")
+ .HasColumnType("datetimeoffset");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("nvarchar(128)");
+
+ b.Property("LicenseNumber")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("Provider");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Assignment3/Models/Error.cs b/Assignment3/Models/Error.cs
new file mode 100644
index 0000000..7554929
--- /dev/null
+++ b/Assignment3/Models/Error.cs
@@ -0,0 +1,15 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Assignment3.Models
+{
+ public class Error
+ {
+ [Key]
+ public Guid Id { get; private set; } = Guid.NewGuid();
+ [Required]
+ public string Message { get; set; } = string.Empty;
+ [Required]
+ [MaxLength(3)]
+ public int status { get; set; }
+ }
+}
diff --git a/Assignment3/Models/Immunization.cs b/Assignment3/Models/Immunization.cs
new file mode 100644
index 0000000..ab4453e
--- /dev/null
+++ b/Assignment3/Models/Immunization.cs
@@ -0,0 +1,30 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Assignment3.Models
+{
+ public class Immunization
+ {
+ [Key]
+ public Guid Id { get; private set; } = Guid.NewGuid();
+
+ [Required]
+ public DateTimeOffset CreationTime { get; private set; } = DateTimeOffset.UtcNow;
+
+ [Required]
+ [MaxLength(128)]
+ public string OfficialName { get; set; } = string.Empty;
+
+ [MaxLength(128)]
+ public string? TradeName { get; set; }
+
+ [Required]
+ [MaxLength(255)]
+ public string LotNumber { get; set; } = string.Empty;
+
+ [Required]
+ public DateTimeOffset ExpirationDate { get; set; }
+
+ public DateTimeOffset? UpdatedTime { get; private set; }
+
+ }
+}
diff --git a/Assignment3/Models/Organization.cs b/Assignment3/Models/Organization.cs
new file mode 100644
index 0000000..7fec494
--- /dev/null
+++ b/Assignment3/Models/Organization.cs
@@ -0,0 +1,37 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Assignment3.Models
+{
+ public class Organization :IValidatableObject
+ {
+ [Key]
+ public Guid Id { get; private set; } = Guid.NewGuid();
+
+ [Required]
+ public DateTimeOffset CreationTime { get; private set; } = DateTimeOffset.UtcNow;
+
+ [Required]
+ [MaxLength(256)]
+ public string Name { get; set; }
+
+ [Required]
+ public String Type { get; set; }
+
+ [Required]
+ public string Address { get; set; }
+
+ // need to add error handling for Guid and possible Creation Time
+ // Can we have it so it just write over user input for creation time to current time?
+ public IEnumerable Validate(ValidationContext validationContext)
+ {
+ // Custom Validation: Type must be one of the allowed values
+ string[] validTypes = { "Hospital", "Clinic", "Pharmacy" };
+
+ if (!Array.Exists(validTypes, t => t.Equals(Type, StringComparison.OrdinalIgnoreCase)))
+ {
+ yield return new ValidationResult("The Organization Type must be one of the following values: Hospital, Clinic, Pharmacy.", new[] { "Type" });
+ }
+ }
+
+ }
+}
diff --git a/Assignment3/Models/Patient.cs b/Assignment3/Models/Patient.cs
new file mode 100644
index 0000000..9e7bbe1
--- /dev/null
+++ b/Assignment3/Models/Patient.cs
@@ -0,0 +1,26 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Assignment3.Models
+{
+ public class Patient
+ {
+
+ [Key]
+ public Guid Id { get; private set; } = Guid.NewGuid(); // Auto-generated
+
+ [Required]
+ public DateTimeOffset CreationTime { get; private set; } = DateTimeOffset.UtcNow; // Auto-generated
+
+ [Required]
+ [MaxLength(128)]
+ public string FirstName { get; set; } = string.Empty;
+
+ [Required]
+ [MaxLength(128)]
+ public string LastName { get; set; } = string.Empty;
+
+ [Required]
+ public DateTimeOffset DateOfBirth { get; set; }
+
+ }
+}
diff --git a/Assignment3/Models/Provider.cs b/Assignment3/Models/Provider.cs
new file mode 100644
index 0000000..dec24f8
--- /dev/null
+++ b/Assignment3/Models/Provider.cs
@@ -0,0 +1,30 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Assignment3.Models
+{
+ public class Provider
+ {
+
+ [Key]
+ public Guid Id { get; private set; } = Guid.NewGuid();
+
+ [Required]
+ public DateTimeOffset CreationTime { get; private set; } = DateTimeOffset.UtcNow;
+
+ [Required]
+ [MaxLength(128)]
+ public string FirstName { get; set; } = string.Empty;
+
+ [Required]
+ [MaxLength(128)]
+ public string LastName { get; set; } = string.Empty;
+
+ [Required]
+ public uint LicenseNumber { get; set; }
+
+ [Required]
+ public string Address { get; set; } = string.Empty;
+
+
+ }
+}
diff --git a/Assignment3/Program.cs b/Assignment3/Program.cs
new file mode 100644
index 0000000..bab75e6
--- /dev/null
+++ b/Assignment3/Program.cs
@@ -0,0 +1,39 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using Assignment3.Data;
+using Assignment3.Middleware;
+namespace Assignment3
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ var builder = WebApplication.CreateBuilder(args);
+ builder.Services.AddDbContext(options =>
+ options.UseSqlServer(builder.Configuration.GetConnectionString("Assignment3Context") ?? throw new InvalidOperationException("Connection string 'Assignment3Context' not found.")));
+
+ // Add services to the container.
+
+ //builder.Services.AddControllers();
+ builder.Services.AddControllers(opts =>
+ {
+ opts.ReturnHttpNotAcceptable = true;
+ })
+ .AddXmlDataContractSerializerFormatters();
+
+ var app = builder.Build();
+
+ // Configure the HTTP request pipeline.
+
+ app.UseHttpsRedirection();
+
+ app.UseAuthorization();
+
+ app.MapControllers();
+
+ app.UseMiddleware();
+
+ app.Run();
+ }
+ }
+}
diff --git a/Assignment3/Properties/launchSettings.json b/Assignment3/Properties/launchSettings.json
new file mode 100644
index 0000000..7a92662
--- /dev/null
+++ b/Assignment3/Properties/launchSettings.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:59185",
+ "sslPort": 44315
+ }
+ },
+ "profiles": {
+ "Assignment3": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "api/Immunizations",
+ "applicationUrl": "https://localhost:7092;http://localhost:5136",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "api/Immunications",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/Assignment3/Properties/serviceDependencies.json b/Assignment3/Properties/serviceDependencies.json
new file mode 100644
index 0000000..6f82557
--- /dev/null
+++ b/Assignment3/Properties/serviceDependencies.json
@@ -0,0 +1,8 @@
+{
+ "dependencies": {
+ "mssql1": {
+ "type": "mssql",
+ "connectionId": "ConnectionStrings:Assignment3Context"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assignment3/Properties/serviceDependencies.local.json b/Assignment3/Properties/serviceDependencies.local.json
new file mode 100644
index 0000000..95d846f
--- /dev/null
+++ b/Assignment3/Properties/serviceDependencies.local.json
@@ -0,0 +1,8 @@
+{
+ "dependencies": {
+ "mssql1": {
+ "type": "mssql.local",
+ "connectionId": "ConnectionStrings:Assignment3Context"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assignment3/appsettings.Development.json b/Assignment3/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/Assignment3/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/Assignment3/appsettings.json b/Assignment3/appsettings.json
new file mode 100644
index 0000000..8541485
--- /dev/null
+++ b/Assignment3/appsettings.json
@@ -0,0 +1,12 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "Assignment3Context": "Server=(localdb)\\mssqllocaldb;Database=Assignment3.Data;Trusted_Connection=True;MultipleActiveResultSets=true"
+ }
+}
\ No newline at end of file