update dotnet version, new ef core migrations
This commit is contained in:
38
Unbinder/Controllers/Api/BaseApiController.cs
Normal file
38
Unbinder/Controllers/Api/BaseApiController.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Unbinder.Repositories;
|
||||||
|
|
||||||
|
namespace Unbinder.Controllers.Api
|
||||||
|
{
|
||||||
|
public abstract class BaseApiController<T> : ControllerBase
|
||||||
|
{
|
||||||
|
protected readonly IBaseRepository<T> repository;
|
||||||
|
|
||||||
|
public BaseApiController(IBaseRepository<T> repository)
|
||||||
|
{
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult UpdateById(int id)
|
||||||
|
{
|
||||||
|
var result = repository.UpdateById(id);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{id}")]
|
||||||
|
public IActionResult DeleteById(int id)
|
||||||
|
{
|
||||||
|
var result = repository.DeleteById(id);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Unbinder/Controllers/Api/RecipeApiController.cs
Normal file
15
Unbinder/Controllers/Api/RecipeApiController.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Unbinder.Models;
|
||||||
|
using Unbinder.Repositories;
|
||||||
|
|
||||||
|
namespace Unbinder.Controllers.Api
|
||||||
|
{
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class RecipeApiController : BaseApiController<Recipe>
|
||||||
|
{
|
||||||
|
public RecipeApiController(IRecipeRepository recipeRepository) : base(recipeRepository)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,59 +5,35 @@ namespace Unbinder.Controllers
|
|||||||
{
|
{
|
||||||
public abstract class BaseController<T> : Controller
|
public abstract class BaseController<T> : Controller
|
||||||
{
|
{
|
||||||
protected readonly IBaseRepository<T> _repository;
|
protected readonly IBaseRepository<T> repository;
|
||||||
|
|
||||||
public BaseController(IBaseRepository<T> repository)
|
public BaseController(IBaseRepository<T> repository)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult GetAll()
|
public IActionResult GetAll()
|
||||||
{
|
{
|
||||||
var result = _repository.GetAll;
|
var result = repository.GetAll;
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(result);
|
return View(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{id}")]
|
|
||||||
public IActionResult GetById(int id)
|
public IActionResult GetById(int id)
|
||||||
{
|
{
|
||||||
var result = _repository.GetById(id);
|
var result = repository.GetById(id);
|
||||||
if (result == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(result);
|
return View(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("{id}")]
|
// mutators exposed in API controller, intended to be called from front end
|
||||||
public IActionResult UpdateById(int id)
|
|
||||||
{
|
|
||||||
var result = _repository.UpdateById(id);
|
|
||||||
if (result == null)
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpDelete("{id}")]
|
|
||||||
public IActionResult DeleteById(int id)
|
|
||||||
{
|
|
||||||
var result = _repository.DeleteById(id);
|
|
||||||
if (result == 0)
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
Unbinder/DB/Initializer.cs
Normal file
27
Unbinder/DB/Initializer.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using Unbinder.Models;
|
||||||
|
|
||||||
|
namespace Unbinder.DB
|
||||||
|
{
|
||||||
|
public static class Initializer
|
||||||
|
{
|
||||||
|
public static int Seed(IApplicationBuilder applicationBuilder)
|
||||||
|
{
|
||||||
|
UnbinderDbContext context = applicationBuilder.ApplicationServices.CreateScope()
|
||||||
|
.ServiceProvider.GetRequiredService<UnbinderDbContext>();
|
||||||
|
|
||||||
|
if (!context.Recipes.Any())
|
||||||
|
{
|
||||||
|
context.Recipes.AddRange(SeedData.InitialRecipes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.Ingredients.Any())
|
||||||
|
{
|
||||||
|
context.Ingredients.AddRange(SeedData.PadThaiIngredients);
|
||||||
|
}
|
||||||
|
|
||||||
|
int insertCount = context.SaveChanges();
|
||||||
|
Console.WriteLine($"Seeded {insertCount} records");
|
||||||
|
return insertCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Unbinder.Models;
|
|
||||||
|
|
||||||
namespace Unbinder.DB
|
|
||||||
{
|
|
||||||
public class RecipeServerDbContext : DbContext
|
|
||||||
{
|
|
||||||
public RecipeServerDbContext(DbContextOptions<RecipeServerDbContext> options) : base(options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbSet<Recipe> Recipes { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
108
Unbinder/DB/SeedData.cs
Normal file
108
Unbinder/DB/SeedData.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using Unbinder.Models;
|
||||||
|
|
||||||
|
namespace Unbinder.DB
|
||||||
|
{
|
||||||
|
public static class SeedData
|
||||||
|
{
|
||||||
|
public static Recipe PadThaiRecipe
|
||||||
|
{
|
||||||
|
get => new()
|
||||||
|
{
|
||||||
|
Name = "Pad Thai",
|
||||||
|
ShortDescription = "A popular noodle dish",
|
||||||
|
Author = "Github Copilot",
|
||||||
|
RecipeText = "1. Cook the noodles according to the package instructions.\n" +
|
||||||
|
"2. In a small bowl, combine the tamarind paste, fish sauce, and brown sugar. Set aside.\n" +
|
||||||
|
"3. Heat the oil in a large wok or skillet over medium-high heat. Add the garlic and stir-fry until fragrant, about 30 seconds. Add the shrimp and stir-fry until pink, about 2 minutes. Add the tofu and cook for 1 minute. Push everything to the side of the wok.\n" +
|
||||||
|
"4. Crack the eggs into the wok and scramble until nearly set, about 1 minute. Add the noodles and pour the sauce over the top. Toss everything to combine.\n" +
|
||||||
|
"5. Add the bean sprouts and green onions and toss to combine. Transfer to a serving platter and top with the cilantro and peanuts. Serve with lime wedges.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Recipe PancakeRecipe
|
||||||
|
{
|
||||||
|
get => new()
|
||||||
|
{
|
||||||
|
Name = "Pancakes",
|
||||||
|
ShortDescription = "A delicious breakfast",
|
||||||
|
Author = "Github Copilot",
|
||||||
|
RecipeText = "1. In a large bowl, whisk together the flour, baking powder, salt, and sugar.\n" +
|
||||||
|
"2. In a separate bowl, whisk together the milk, eggs, and melted butter.\n" +
|
||||||
|
"3. Add the wet ingredients to the dry ingredients and whisk until just combined. Let the batter rest for 5 minutes.\n" +
|
||||||
|
"4. Heat a large nonstick skillet or griddle over medium-low heat. Add a little butter to the pan and swirl to coat. Add ⅓ cup of the batter to the pan and cook until the edges are set and bubbles form on the surface, about 2 minutes. Flip and cook for 1 minute more. Repeat with the remaining batter.\n" +
|
||||||
|
"5. Serve with butter and maple syrup.",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Recipe[] InitialRecipes => new Recipe[] { PadThaiRecipe, PancakeRecipe };
|
||||||
|
|
||||||
|
public static Ingredient[] PadThaiIngredients
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Cilantro",
|
||||||
|
Description = "Aromatic herb with a citrusy flavor",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Lime",
|
||||||
|
Description = "A citrus fruit with a sour taste",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Peanuts",
|
||||||
|
Description = "A legume that grows underground",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Rice Noodles",
|
||||||
|
Description = "Noodles made from rice flour",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Eggs",
|
||||||
|
Description = "A breakfast staple",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Tofu",
|
||||||
|
Description = "A soy-based meat substitute",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static Ingredient[] PancakeIngredients
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "All purpose flour",
|
||||||
|
Description = "A versatile flour",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Baking powder",
|
||||||
|
Description = "A leavening agent",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Salt",
|
||||||
|
Description = "A mineral",
|
||||||
|
},
|
||||||
|
new Ingredient
|
||||||
|
{
|
||||||
|
Name = "Granulated sugar",
|
||||||
|
Description = "A sweetener",
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Ingredient[] InitialIngredients => PadThaiIngredients.Concat(PancakeIngredients).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Unbinder/DB/UnbinderDbContext.cs
Normal file
15
Unbinder/DB/UnbinderDbContext.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Unbinder.Models;
|
||||||
|
|
||||||
|
namespace Unbinder.DB
|
||||||
|
{
|
||||||
|
public class UnbinderDbContext : DbContext
|
||||||
|
{
|
||||||
|
public UnbinderDbContext(DbContextOptions<UnbinderDbContext> options) : base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbSet<Recipe> Recipes { get; set; }
|
||||||
|
public DbSet<Ingredient> Ingredients { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
97
Unbinder/Migrations/20231117145840_InitialMigration.Designer.cs
generated
Normal file
97
Unbinder/Migrations/20231117145840_InitialMigration.Designer.cs
generated
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Unbinder.DB;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Unbinder.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(UnbinderDbContext))]
|
||||||
|
[Migration("20231117145840_InitialMigration")]
|
||||||
|
partial class InitialMigration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.0")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Ingredient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("IngredientId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("IngredientId"));
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int?>("RecipeId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("IngredientId");
|
||||||
|
|
||||||
|
b.HasIndex("RecipeId");
|
||||||
|
|
||||||
|
b.ToTable("Ingredients");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Recipe", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RecipeId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("RecipeId"));
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("RecipeText")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ShortDescription")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("RecipeId");
|
||||||
|
|
||||||
|
b.ToTable("Recipes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Ingredient", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Unbinder.Models.Recipe", null)
|
||||||
|
.WithMany("Ingredients")
|
||||||
|
.HasForeignKey("RecipeId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Recipe", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Ingredients");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
Unbinder/Migrations/20231117145840_InitialMigration.cs
Normal file
66
Unbinder/Migrations/20231117145840_InitialMigration.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Unbinder.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class InitialMigration : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Recipes",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
RecipeId = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
|
ShortDescription = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
|
Author = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
RecipeText = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
ImageUrl = table.Column<string>(type: "nvarchar(max)", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Recipes", x => x.RecipeId);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Ingredients",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
IngredientId = table.Column<int>(type: "int", nullable: false)
|
||||||
|
.Annotation("SqlServer:Identity", "1, 1"),
|
||||||
|
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
|
||||||
|
Description = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
RecipeId = table.Column<int>(type: "int", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Ingredients", x => x.IngredientId);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Ingredients_Recipes_RecipeId",
|
||||||
|
column: x => x.RecipeId,
|
||||||
|
principalTable: "Recipes",
|
||||||
|
principalColumn: "RecipeId");
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Ingredients_RecipeId",
|
||||||
|
table: "Ingredients",
|
||||||
|
column: "RecipeId");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Ingredients");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Recipes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
79
Unbinder/Migrations/20231117150919_RemoveIngredientArray.Designer.cs
generated
Normal file
79
Unbinder/Migrations/20231117150919_RemoveIngredientArray.Designer.cs
generated
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Unbinder.DB;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Unbinder.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(UnbinderDbContext))]
|
||||||
|
[Migration("20231117150919_RemoveIngredientArray")]
|
||||||
|
partial class RemoveIngredientArray
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.0")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Ingredient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("IngredientId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("IngredientId"));
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("IngredientId");
|
||||||
|
|
||||||
|
b.ToTable("Ingredients");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Recipe", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RecipeId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("RecipeId"));
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("RecipeText")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ShortDescription")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("RecipeId");
|
||||||
|
|
||||||
|
b.ToTable("Recipes");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
Unbinder/Migrations/20231117150919_RemoveIngredientArray.cs
Normal file
48
Unbinder/Migrations/20231117150919_RemoveIngredientArray.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Unbinder.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class RemoveIngredientArray : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_Ingredients_Recipes_RecipeId",
|
||||||
|
table: "Ingredients");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_Ingredients_RecipeId",
|
||||||
|
table: "Ingredients");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "RecipeId",
|
||||||
|
table: "Ingredients");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "RecipeId",
|
||||||
|
table: "Ingredients",
|
||||||
|
type: "int",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Ingredients_RecipeId",
|
||||||
|
table: "Ingredients",
|
||||||
|
column: "RecipeId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_Ingredients_Recipes_RecipeId",
|
||||||
|
table: "Ingredients",
|
||||||
|
column: "RecipeId",
|
||||||
|
principalTable: "Recipes",
|
||||||
|
principalColumn: "RecipeId");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
Unbinder/Migrations/UnbinderDbContextModelSnapshot.cs
Normal file
76
Unbinder/Migrations/UnbinderDbContextModelSnapshot.cs
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Unbinder.DB;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Unbinder.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(UnbinderDbContext))]
|
||||||
|
partial class UnbinderDbContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.0")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||||
|
|
||||||
|
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Ingredient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("IngredientId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("IngredientId"));
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("IngredientId");
|
||||||
|
|
||||||
|
b.ToTable("Ingredients");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Unbinder.Models.Recipe", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RecipeId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("RecipeId"));
|
||||||
|
|
||||||
|
b.Property<string>("Author")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ImageUrl")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("RecipeText")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<string>("ShortDescription")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.HasKey("RecipeId");
|
||||||
|
|
||||||
|
b.ToTable("Recipes");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
public int RecipeId { get; init; }
|
public int RecipeId { get; init; }
|
||||||
public string Name {get; init; } = default!;
|
public string Name {get; init; } = default!;
|
||||||
public string ShortDescription { get; init; } = default!;
|
public string ShortDescription { get; init; } = default!;
|
||||||
public Ingredient[]? Ingredients {get; init; }
|
public string? Author { get; init; }
|
||||||
|
|
||||||
public string? RecipeText { get; init; }
|
public string? RecipeText { get; init; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
@*
|
@model IEnumerable<Recipe>
|
||||||
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
|
||||||
*@
|
|
||||||
@{
|
@{
|
||||||
|
ViewBag.Title = "Recipes";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<div id="recipe-list-container">
|
||||||
|
@foreach (var recipe in @Model)
|
||||||
|
{
|
||||||
|
<p>@recipe.Name</p>
|
||||||
|
<p>@recipe.RecipeText</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
5
Unbinder/Pages/Recipes/RecipeId.cshtml
Normal file
5
Unbinder/Pages/Recipes/RecipeId.cshtml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
@model Recipe
|
||||||
|
|
||||||
|
<div id="recipe-details-by-id">
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
@using Unbinder
|
@using Unbinder
|
||||||
|
@using Unbinder.Models
|
||||||
|
@using Unbinder.ViewModels
|
||||||
|
@using Unbinder.Controllers
|
||||||
|
|
||||||
@namespace Unbinder.Pages
|
@namespace Unbinder.Pages
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
|||||||
@@ -3,24 +3,31 @@ using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||||
using Microsoft.Identity.Web;
|
using Microsoft.Identity.Web;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Identity.Web.UI;
|
using Microsoft.Identity.Web.UI;
|
||||||
|
using Unbinder.DB;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
|
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
|
||||||
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
|
.AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"));
|
||||||
|
|
||||||
builder.Services.AddAuthorization(options =>
|
builder.Services.AddAuthorization(options =>
|
||||||
{
|
|
||||||
// By default, all incoming requests will be authorized according to the default policy.
|
// By default, all incoming requests will be authorized according to the default policy.
|
||||||
options.FallbackPolicy = options.DefaultPolicy;
|
options.FallbackPolicy = options.DefaultPolicy);
|
||||||
});
|
|
||||||
builder.Services.AddRazorPages()
|
builder.Services.AddRazorPages()
|
||||||
.AddMicrosoftIdentityUI();
|
.AddMicrosoftIdentityUI();
|
||||||
|
|
||||||
builder.Services.AddMvc();
|
builder.Services.AddMvc();
|
||||||
|
|
||||||
|
builder.Services.AddDbContext<UnbinderDbContext>(options =>
|
||||||
|
options.UseSqlServer(connectionString, providerOptions =>
|
||||||
|
providerOptions.EnableRetryOnFailure())
|
||||||
|
);
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Configure the HTTP request pipeline.
|
||||||
@@ -42,4 +49,6 @@ app.UseAuthorization();
|
|||||||
app.MapRazorPages();
|
app.MapRazorPages();
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
|
Initializer.Seed(app);
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ namespace Unbinder.Repositories
|
|||||||
{
|
{
|
||||||
public class RecipeRepository : IRecipeRepository
|
public class RecipeRepository : IRecipeRepository
|
||||||
{
|
{
|
||||||
private readonly RecipeServerDbContext _dbContext;
|
private readonly UnbinderDbContext _dbContext;
|
||||||
|
|
||||||
public RecipeRepository(RecipeServerDbContext dbContext)
|
public RecipeRepository(UnbinderDbContext dbContext)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,29 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<LangVersion>preview</LangVersion>
|
||||||
<UserSecretsId>aspnet-Unbinder-d1949c36-2a4b-40ef-b530-fd5a24526f87</UserSecretsId>
|
<UserSecretsId>aspnet-Unbinder-d1949c36-2a4b-40ef-b530-fd5a24526f87</UserSecretsId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.21" NoWarn="NU1605" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" NoWarn="NU1605" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.21" NoWarn="NU1605" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.0" NoWarn="NU1605" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.25" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Identity.Web" Version="2.13.1" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
|
||||||
<PackageReference Include="Microsoft.Identity.Web.UI" Version="2.13.1" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Identity.Web" Version="2.15.3" />
|
||||||
|
<PackageReference Include="Microsoft.Identity.Web.UI" Version="2.15.3" />
|
||||||
|
<PackageReference Include="Microsoft.SqlServer.Server" Version="1.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="ViewModels\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
14
Unbinder/ViewModels/RecipeListViewModel.cs
Normal file
14
Unbinder/ViewModels/RecipeListViewModel.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Unbinder.Models;
|
||||||
|
|
||||||
|
namespace Unbinder.ViewModels
|
||||||
|
{
|
||||||
|
public class RecipeListViewModel
|
||||||
|
{
|
||||||
|
public IEnumerable<Recipe> Recipes { get; }
|
||||||
|
|
||||||
|
public RecipeListViewModel(IEnumerable<Recipe> recipes)
|
||||||
|
{
|
||||||
|
Recipes = recipes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,9 @@
|
|||||||
"ClientId": "c604c109-d54d-4b68-a267-f8f00242a655",
|
"ClientId": "c604c109-d54d-4b68-a267-f8f00242a655",
|
||||||
"CallbackPath": "/signin-oidc"
|
"CallbackPath": "/signin-oidc"
|
||||||
},
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=Unbinder11623"
|
||||||
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
|
|||||||
Reference in New Issue
Block a user