diff --git a/DBConnection/Migrations/PostgresSql/20220717133208_Fix up UserNovel model and add index on User Email.Designer.cs b/DBConnection/Migrations/PostgresSql/20220717133208_Fix up UserNovel model and add index on User Email.Designer.cs new file mode 100644 index 0000000..ace620d --- /dev/null +++ b/DBConnection/Migrations/PostgresSql/20220717133208_Fix up UserNovel model and add index on User Email.Designer.cs @@ -0,0 +1,275 @@ +// +using System; +using DBConnection.Contexts; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DBConnection.Migrations.PostgresSql +{ + [DbContext(typeof(PostgresSqlAppDbContext))] + [Migration("20220717133208_Fix up UserNovel model and add index on User Email")] + partial class FixupUserNovelmodelandaddindexonUserEmail + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("NovelTag", b => + { + b.Property("NovelsUrl") + .HasColumnType("text"); + + b.Property("TagsTagValue") + .HasColumnType("text"); + + b.HasKey("NovelsUrl", "TagsTagValue"); + + b.HasIndex("TagsTagValue"); + + b.ToTable("NovelTag"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Author", b => + { + b.Property("Url") + .HasColumnType("text"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Url"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Chapter", b => + { + b.Property("Url") + .HasColumnType("text"); + + b.Property("ChapterNumber") + .HasColumnType("integer"); + + b.Property("Content") + .HasColumnType("text"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone"); + + b.Property("DatePosted") + .HasColumnType("timestamp with time zone"); + + b.Property("DateUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("LastContentFetch") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("NovelUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("RawContent") + .HasColumnType("text"); + + b.HasKey("Url"); + + b.HasIndex("NovelUrl"); + + b.ToTable("Chapters"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => + { + b.Property("Url") + .HasColumnType("text"); + + b.Property("AuthorUrl") + .HasColumnType("text"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone"); + + b.Property("DatePosted") + .HasColumnType("timestamp with time zone"); + + b.Property("Guid") + .HasColumnType("uuid"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Url"); + + b.HasIndex("AuthorUrl"); + + b.HasIndex("Guid"); + + b.ToTable("Novels"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Tag", b => + { + b.Property("TagValue") + .HasColumnType("text"); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone"); + + b.HasKey("TagValue"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateCreated") + .HasColumnType("timestamp with time zone"); + + b.Property("DateModified") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.UserNovel", b => + { + b.Property("NovelUrl") + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.Property("LastChapterRead") + .HasColumnType("integer"); + + b.HasKey("NovelUrl", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNovels"); + }); + + modelBuilder.Entity("NovelTag", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", null) + .WithMany() + .HasForeignKey("NovelsUrl") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Treestar.Shared.Models.DBDomain.Tag", null) + .WithMany() + .HasForeignKey("TagsTagValue") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Chapter", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", "Novel") + .WithMany("Chapters") + .HasForeignKey("NovelUrl") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Novel"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Author", "Author") + .WithMany("Novels") + .HasForeignKey("AuthorUrl"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.UserNovel", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", "Novel") + .WithMany() + .HasForeignKey("NovelUrl") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Treestar.Shared.Models.DBDomain.User", "User") + .WithMany("WatchedNovels") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Novel"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Author", b => + { + b.Navigation("Novels"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => + { + b.Navigation("Chapters"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.User", b => + { + b.Navigation("WatchedNovels"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DBConnection/Migrations/PostgresSql/20220717133208_Fix up UserNovel model and add index on User Email.cs b/DBConnection/Migrations/PostgresSql/20220717133208_Fix up UserNovel model and add index on User Email.cs new file mode 100644 index 0000000..2f2bd50 --- /dev/null +++ b/DBConnection/Migrations/PostgresSql/20220717133208_Fix up UserNovel model and add index on User Email.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DBConnection.Migrations.PostgresSql +{ + public partial class FixupUserNovelmodelandaddindexonUserEmail : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateIndex( + name: "IX_Users_Email", + table: "Users", + column: "Email"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Users_Email", + table: "Users"); + } + } +} diff --git a/DBConnection/Migrations/PostgresSql/PostgresSqlAppDbContextModelSnapshot.cs b/DBConnection/Migrations/PostgresSql/PostgresSqlAppDbContextModelSnapshot.cs index f219fe5..83f6c51 100644 --- a/DBConnection/Migrations/PostgresSql/PostgresSqlAppDbContextModelSnapshot.cs +++ b/DBConnection/Migrations/PostgresSql/PostgresSqlAppDbContextModelSnapshot.cs @@ -176,6 +176,8 @@ namespace DBConnection.Migrations.PostgresSql b.HasKey("Id"); + b.HasIndex("Email"); + b.ToTable("Users"); }); @@ -214,11 +216,13 @@ namespace DBConnection.Migrations.PostgresSql modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Chapter", b => { - b.HasOne("Treestar.Shared.Models.DBDomain.Novel", null) + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", "Novel") .WithMany("Chapters") .HasForeignKey("NovelUrl") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Novel"); }); modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => diff --git a/DBConnection/Migrations/Sqlite/20220717133151_Fix up UserNovel model and add index on User Email.Designer.cs b/DBConnection/Migrations/Sqlite/20220717133151_Fix up UserNovel model and add index on User Email.Designer.cs new file mode 100644 index 0000000..470a978 --- /dev/null +++ b/DBConnection/Migrations/Sqlite/20220717133151_Fix up UserNovel model and add index on User Email.Designer.cs @@ -0,0 +1,268 @@ +// +using System; +using DBConnection.Contexts; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DBConnection.Migrations.Sqlite +{ + [DbContext(typeof(SqliteAppDbContext))] + [Migration("20220717133151_Fix up UserNovel model and add index on User Email")] + partial class FixupUserNovelmodelandaddindexonUserEmail + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.7"); + + modelBuilder.Entity("NovelTag", b => + { + b.Property("NovelsUrl") + .HasColumnType("TEXT"); + + b.Property("TagsTagValue") + .HasColumnType("TEXT"); + + b.HasKey("NovelsUrl", "TagsTagValue"); + + b.HasIndex("TagsTagValue"); + + b.ToTable("NovelTag"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Author", b => + { + b.Property("Url") + .HasColumnType("TEXT"); + + b.Property("DateCreated") + .HasColumnType("TEXT"); + + b.Property("DateModified") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Url"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Chapter", b => + { + b.Property("Url") + .HasColumnType("TEXT"); + + b.Property("ChapterNumber") + .HasColumnType("INTEGER"); + + b.Property("Content") + .HasColumnType("TEXT"); + + b.Property("DateCreated") + .HasColumnType("TEXT"); + + b.Property("DateModified") + .HasColumnType("TEXT"); + + b.Property("DatePosted") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("LastContentFetch") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("NovelUrl") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RawContent") + .HasColumnType("TEXT"); + + b.HasKey("Url"); + + b.HasIndex("NovelUrl"); + + b.ToTable("Chapters"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => + { + b.Property("Url") + .HasColumnType("TEXT"); + + b.Property("AuthorUrl") + .HasColumnType("TEXT"); + + b.Property("DateCreated") + .HasColumnType("TEXT"); + + b.Property("DateModified") + .HasColumnType("TEXT"); + + b.Property("DatePosted") + .HasColumnType("TEXT"); + + b.Property("Guid") + .HasColumnType("TEXT"); + + b.Property("LastUpdated") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Url"); + + b.HasIndex("AuthorUrl"); + + b.HasIndex("Guid"); + + b.ToTable("Novels"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Tag", b => + { + b.Property("TagValue") + .HasColumnType("TEXT"); + + b.Property("DateCreated") + .HasColumnType("TEXT"); + + b.Property("DateModified") + .HasColumnType("TEXT"); + + b.HasKey("TagValue"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateCreated") + .HasColumnType("TEXT"); + + b.Property("DateModified") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.UserNovel", b => + { + b.Property("NovelUrl") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.Property("LastChapterRead") + .HasColumnType("INTEGER"); + + b.HasKey("NovelUrl", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNovels"); + }); + + modelBuilder.Entity("NovelTag", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", null) + .WithMany() + .HasForeignKey("NovelsUrl") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Treestar.Shared.Models.DBDomain.Tag", null) + .WithMany() + .HasForeignKey("TagsTagValue") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Chapter", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", "Novel") + .WithMany("Chapters") + .HasForeignKey("NovelUrl") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Novel"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Author", "Author") + .WithMany("Novels") + .HasForeignKey("AuthorUrl"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.UserNovel", b => + { + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", "Novel") + .WithMany() + .HasForeignKey("NovelUrl") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Treestar.Shared.Models.DBDomain.User", "User") + .WithMany("WatchedNovels") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Novel"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Author", b => + { + b.Navigation("Novels"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => + { + b.Navigation("Chapters"); + }); + + modelBuilder.Entity("Treestar.Shared.Models.DBDomain.User", b => + { + b.Navigation("WatchedNovels"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DBConnection/Migrations/Sqlite/20220717133151_Fix up UserNovel model and add index on User Email.cs b/DBConnection/Migrations/Sqlite/20220717133151_Fix up UserNovel model and add index on User Email.cs new file mode 100644 index 0000000..4010a61 --- /dev/null +++ b/DBConnection/Migrations/Sqlite/20220717133151_Fix up UserNovel model and add index on User Email.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DBConnection.Migrations.Sqlite +{ + public partial class FixupUserNovelmodelandaddindexonUserEmail : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateIndex( + name: "IX_Users_Email", + table: "Users", + column: "Email"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Users_Email", + table: "Users"); + } + } +} diff --git a/DBConnection/Migrations/Sqlite/SqliteAppDbContextModelSnapshot.cs b/DBConnection/Migrations/Sqlite/SqliteAppDbContextModelSnapshot.cs index 220fecc..dda7091 100644 --- a/DBConnection/Migrations/Sqlite/SqliteAppDbContextModelSnapshot.cs +++ b/DBConnection/Migrations/Sqlite/SqliteAppDbContextModelSnapshot.cs @@ -169,6 +169,8 @@ namespace DBConnection.Migrations.Sqlite b.HasKey("Id"); + b.HasIndex("Email"); + b.ToTable("Users"); }); @@ -207,11 +209,13 @@ namespace DBConnection.Migrations.Sqlite modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Chapter", b => { - b.HasOne("Treestar.Shared.Models.DBDomain.Novel", null) + b.HasOne("Treestar.Shared.Models.DBDomain.Novel", "Novel") .WithMany("Chapters") .HasForeignKey("NovelUrl") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + + b.Navigation("Novel"); }); modelBuilder.Entity("Treestar.Shared.Models.DBDomain.Novel", b => diff --git a/DBConnection/Repositories/NovelRepository.cs b/DBConnection/Repositories/NovelRepository.cs index a80d6f5..fc44a7e 100644 --- a/DBConnection/Repositories/NovelRepository.cs +++ b/DBConnection/Repositories/NovelRepository.cs @@ -19,24 +19,27 @@ public class NovelRepository : BaseRepository, INovelRepository public override async Task Upsert(Novel entity, bool saveAfter=true) { + var dbEntity = await GetIncluded(entity) ?? entity; // Author if (entity.Author != null) { - entity.Author = await _authorRepository.Upsert(entity.Author, saveAfter); + entity.Author = await _authorRepository.Upsert(entity.Author, false); } //Tags var newTags = await _tagRepository.UpsertMany(entity.Tags, false); - entity.Tags.Clear(); - entity.Tags = newTags.ToList(); - //chapters + + //chapters are getting deleted now that their required... var newChapters = await _chapterRepository.UpsertMany(entity.Chapters, false); - entity.Chapters.Clear(); - entity.Chapters = newChapters.ToList(); + // update in db - var dbEntity = await GetIncluded(entity) ?? entity; entity.Guid = dbEntity.Guid; DbContext.Entry(dbEntity).CurrentValues.SetValues(entity); + dbEntity.Tags.Clear(); + dbEntity.Tags.AddRange(newTags); + dbEntity.Chapters.Clear(); + dbEntity.Chapters.AddRange(newChapters); + if (DbContext.Entry(dbEntity).State == EntityState.Detached) { dbEntity.Guid = Guid.NewGuid(); diff --git a/Treestar.Shared/Models/DBDomain/Chapter.cs b/Treestar.Shared/Models/DBDomain/Chapter.cs index 4f4d242..0b70d24 100644 --- a/Treestar.Shared/Models/DBDomain/Chapter.cs +++ b/Treestar.Shared/Models/DBDomain/Chapter.cs @@ -14,7 +14,7 @@ namespace Treestar.Shared.Models.DBDomain public DateTime? DateUpdated { get; set; } public DateTime? LastContentFetch { get; set; } [Required] - public string NovelUrl { get; set; } + public Novel Novel { get; set; } protected bool Equals(Chapter other) { diff --git a/Treestar.Shared/Models/DBDomain/User.cs b/Treestar.Shared/Models/DBDomain/User.cs index bf49392..db7a011 100644 --- a/Treestar.Shared/Models/DBDomain/User.cs +++ b/Treestar.Shared/Models/DBDomain/User.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; +using Microsoft.EntityFrameworkCore; namespace Treestar.Shared.Models.DBDomain { + [Index(nameof(Email))] public class User : BaseEntity { [Key] diff --git a/Treestar.Shared/Models/DBDomain/UserNovel.cs b/Treestar.Shared/Models/DBDomain/UserNovel.cs index aad0d31..f053a1a 100644 --- a/Treestar.Shared/Models/DBDomain/UserNovel.cs +++ b/Treestar.Shared/Models/DBDomain/UserNovel.cs @@ -4,10 +4,10 @@ namespace Treestar.Shared.Models.DBDomain { public class UserNovel { - [JsonIgnore] public int UserId { get; set; } public string NovelUrl { get; set; } public Novel Novel { get; set; } + [JsonIgnore] public User User { get; set; } public int LastChapterRead { get; set; } } diff --git a/WebNovelPortal/Controllers/AccountController.cs b/WebNovelPortal/Controllers/AccountController.cs new file mode 100644 index 0000000..882200f --- /dev/null +++ b/WebNovelPortal/Controllers/AccountController.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace WebNovelPortal.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class AccountController : ControllerBase + { + [HttpGet] + [Route("account/login")] + public async Task Login() + { + await HttpContext.ChallengeAsync(); + } + + [HttpGet] + [Route("account/logout")] + public async Task Logout() + { + await HttpContext.SignOutAsync(); + } + } +} diff --git a/WebNovelPortal/Dockerfile b/WebNovelPortal/Dockerfile index 5d52288..7ed412d 100644 --- a/WebNovelPortal/Dockerfile +++ b/WebNovelPortal/Dockerfile @@ -6,6 +6,7 @@ EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["WebNovelPortal/WebNovelPortal.csproj", "WebNovelPortal/"] +COPY ["Treestar.Shared/Treestar.Shared.csproj", "Treestar.Shared/"] RUN dotnet restore "WebNovelPortal/WebNovelPortal.csproj" COPY . . WORKDIR "/src/WebNovelPortal" diff --git a/WebNovelPortal/Program.cs b/WebNovelPortal/Program.cs index ca5ba2d..68fcd31 100644 --- a/WebNovelPortal/Program.cs +++ b/WebNovelPortal/Program.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using Newtonsoft.Json; using WebNovelPortal.AccessLayers; var builder = WebApplication.CreateBuilder(args); @@ -8,6 +9,10 @@ var builder = WebApplication.CreateBuilder(args); builder.Services.AddScoped(fac => new WebApiAccessLayer(builder.Configuration["WebAPIUrl"])); builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); +builder.Services.AddControllers().AddNewtonsoftJson(opt => +{ + opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; +}); var app = builder.Build(); @@ -27,5 +32,6 @@ app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); +app.MapControllers(); app.Run(); \ No newline at end of file diff --git a/WebNovelPortal/WebNovelPortal.csproj b/WebNovelPortal/WebNovelPortal.csproj index 69b0f64..06d286a 100644 --- a/WebNovelPortal/WebNovelPortal.csproj +++ b/WebNovelPortal/WebNovelPortal.csproj @@ -8,6 +8,8 @@ + + @@ -15,4 +17,9 @@ + + + + + diff --git a/WebNovelPortalAPI/Dockerfile b/WebNovelPortalAPI/Dockerfile index 52ba942..8576262 100644 --- a/WebNovelPortalAPI/Dockerfile +++ b/WebNovelPortalAPI/Dockerfile @@ -7,7 +7,7 @@ FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["WebNovelPortalAPI/WebNovelPortalAPI.csproj", "WebNovelPortalAPI/"] COPY ["DBConnection/DBConnection.csproj", "DBConnection/"] -COPY ["Shared/Shared.csproj", "Shared/"] +COPY ["Treestar.Shared/Treestar.Shared.csproj", "Treestar.Shared/"] RUN dotnet restore "WebNovelPortalAPI/WebNovelPortalAPI.csproj" COPY . . WORKDIR "/src/WebNovelPortalAPI"