mirror of https://github.com/abpframework/abp.git
29 changed files with 13713 additions and 70389 deletions
@ -0,0 +1,586 @@ |
|||||
|
// <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 Volo.BloggingTestApp.EntityFrameworkCore; |
||||
|
|
||||
|
namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations |
||||
|
{ |
||||
|
[DbContext(typeof(BloggingTestAppDbContext))] |
||||
|
[Migration("20180911082243_added_CoverImage")] |
||||
|
partial class added_CoverImage |
||||
|
{ |
||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
|
{ |
||||
|
#pragma warning disable 612, 618
|
||||
|
modelBuilder |
||||
|
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846") |
||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 128) |
||||
|
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("NormalizedName") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("NormalizedName"); |
||||
|
|
||||
|
b.ToTable("AbpRoles"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<string>("ClaimType") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("ClaimValue") |
||||
|
.HasMaxLength(1024); |
||||
|
|
||||
|
b.Property<Guid>("RoleId"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("RoleId"); |
||||
|
|
||||
|
b.ToTable("AbpRoleClaims"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<int>("AccessFailedCount") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("AccessFailedCount") |
||||
|
.HasDefaultValue(0); |
||||
|
|
||||
|
b.Property<string>("ConcurrencyStamp") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("ConcurrencyStamp") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("Email") |
||||
|
.HasColumnName("Email") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<bool>("EmailConfirmed") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("EmailConfirmed") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<string>("ExtraProperties") |
||||
|
.HasColumnName("ExtraProperties"); |
||||
|
|
||||
|
b.Property<bool>("LockoutEnabled") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("LockoutEnabled") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<DateTimeOffset?>("LockoutEnd"); |
||||
|
|
||||
|
b.Property<string>("NormalizedEmail") |
||||
|
.HasColumnName("NormalizedEmail") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("NormalizedUserName") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("NormalizedUserName") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("PasswordHash") |
||||
|
.HasColumnName("PasswordHash") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("PhoneNumber") |
||||
|
.HasColumnName("PhoneNumber") |
||||
|
.HasMaxLength(16); |
||||
|
|
||||
|
b.Property<bool>("PhoneNumberConfirmed") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("PhoneNumberConfirmed") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<string>("SecurityStamp") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("SecurityStamp") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId") |
||||
|
.HasColumnName("TenantId"); |
||||
|
|
||||
|
b.Property<bool>("TwoFactorEnabled") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("TwoFactorEnabled") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<string>("UserName") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("UserName") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("Email"); |
||||
|
|
||||
|
b.HasIndex("NormalizedEmail"); |
||||
|
|
||||
|
b.HasIndex("NormalizedUserName"); |
||||
|
|
||||
|
b.HasIndex("UserName"); |
||||
|
|
||||
|
b.ToTable("AbpUsers"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<string>("ClaimType") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("ClaimValue") |
||||
|
.HasMaxLength(1024); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId"); |
||||
|
|
||||
|
b.Property<Guid>("UserId"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("UserId"); |
||||
|
|
||||
|
b.ToTable("AbpUserClaims"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => |
||||
|
{ |
||||
|
b.Property<Guid>("UserId"); |
||||
|
|
||||
|
b.Property<string>("LoginProvider") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("ProviderDisplayName") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ProviderKey") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(196); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId"); |
||||
|
|
||||
|
b.HasKey("UserId", "LoginProvider"); |
||||
|
|
||||
|
b.HasIndex("LoginProvider", "ProviderKey"); |
||||
|
|
||||
|
b.ToTable("AbpUserLogins"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => |
||||
|
{ |
||||
|
b.Property<Guid>("UserId"); |
||||
|
|
||||
|
b.Property<Guid>("RoleId"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId"); |
||||
|
|
||||
|
b.HasKey("UserId", "RoleId"); |
||||
|
|
||||
|
b.HasIndex("RoleId", "UserId"); |
||||
|
|
||||
|
b.ToTable("AbpUserRoles"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => |
||||
|
{ |
||||
|
b.Property<Guid>("UserId"); |
||||
|
|
||||
|
b.Property<string>("LoginProvider") |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("Name"); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId"); |
||||
|
|
||||
|
b.Property<string>("Value"); |
||||
|
|
||||
|
b.HasKey("UserId", "LoginProvider", "Name"); |
||||
|
|
||||
|
b.ToTable("AbpUserTokens"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ProviderKey") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("ProviderName") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<Guid?>("TenantId"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("Name", "ProviderName", "ProviderKey"); |
||||
|
|
||||
|
b.ToTable("AbpPermissionGrants"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(128); |
||||
|
|
||||
|
b.Property<string>("ProviderKey") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("ProviderName") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<string>("Value") |
||||
|
.IsRequired() |
||||
|
.HasMaxLength(2048); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("Name", "ProviderName", "ProviderKey"); |
||||
|
|
||||
|
b.ToTable("AbpSettings"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Blogs.Blog", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<Guid?>("DeleterId") |
||||
|
.HasColumnName("DeleterId"); |
||||
|
|
||||
|
b.Property<DateTime?>("DeletionTime") |
||||
|
.HasColumnName("DeletionTime"); |
||||
|
|
||||
|
b.Property<string>("Description") |
||||
|
.HasColumnName("Description") |
||||
|
.HasMaxLength(1024); |
||||
|
|
||||
|
b.Property<bool>("IsDeleted") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("IsDeleted") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("Name") |
||||
|
.HasMaxLength(256); |
||||
|
|
||||
|
b.Property<string>("ShortName") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("ShortName") |
||||
|
.HasMaxLength(32); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("BlgBlogs"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Comments.Comment", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<Guid?>("DeleterId") |
||||
|
.HasColumnName("DeleterId"); |
||||
|
|
||||
|
b.Property<DateTime?>("DeletionTime") |
||||
|
.HasColumnName("DeletionTime"); |
||||
|
|
||||
|
b.Property<bool>("IsDeleted") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("IsDeleted") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.Property<Guid>("PostId") |
||||
|
.HasColumnName("PostId"); |
||||
|
|
||||
|
b.Property<Guid?>("RepliedCommentId") |
||||
|
.HasColumnName("RepliedCommentId"); |
||||
|
|
||||
|
b.Property<string>("Text") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("Text") |
||||
|
.HasMaxLength(1024); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("PostId"); |
||||
|
|
||||
|
b.HasIndex("RepliedCommentId"); |
||||
|
|
||||
|
b.ToTable("BlgComments"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Posts.Post", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<Guid>("BlogId") |
||||
|
.HasColumnName("BlogId"); |
||||
|
|
||||
|
b.Property<string>("Content") |
||||
|
.HasColumnName("Content") |
||||
|
.HasMaxLength(1048576); |
||||
|
|
||||
|
b.Property<string>("CoverImage") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("CoverImage"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<Guid?>("DeleterId") |
||||
|
.HasColumnName("DeleterId"); |
||||
|
|
||||
|
b.Property<DateTime?>("DeletionTime") |
||||
|
.HasColumnName("DeletionTime"); |
||||
|
|
||||
|
b.Property<bool>("IsDeleted") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("IsDeleted") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.Property<int>("ReadCount"); |
||||
|
|
||||
|
b.Property<string>("Title") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("Title") |
||||
|
.HasMaxLength(512); |
||||
|
|
||||
|
b.Property<string>("Url") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("Url") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.HasIndex("BlogId"); |
||||
|
|
||||
|
b.ToTable("BlgPosts"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Posts.PostTag", b => |
||||
|
{ |
||||
|
b.Property<Guid>("PostId") |
||||
|
.HasColumnName("PostId"); |
||||
|
|
||||
|
b.Property<Guid>("TagId") |
||||
|
.HasColumnName("TagId"); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId"); |
||||
|
|
||||
|
b.HasKey("PostId", "TagId"); |
||||
|
|
||||
|
b.HasIndex("TagId"); |
||||
|
|
||||
|
b.ToTable("BlgPostTags"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Tagging.Tag", b => |
||||
|
{ |
||||
|
b.Property<Guid>("Id") |
||||
|
.ValueGeneratedOnAdd(); |
||||
|
|
||||
|
b.Property<DateTime>("CreationTime") |
||||
|
.HasColumnName("CreationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("CreatorId") |
||||
|
.HasColumnName("CreatorId"); |
||||
|
|
||||
|
b.Property<Guid?>("DeleterId") |
||||
|
.HasColumnName("DeleterId"); |
||||
|
|
||||
|
b.Property<DateTime?>("DeletionTime") |
||||
|
.HasColumnName("DeletionTime"); |
||||
|
|
||||
|
b.Property<string>("Description") |
||||
|
.HasColumnName("Description") |
||||
|
.HasMaxLength(512); |
||||
|
|
||||
|
b.Property<bool>("IsDeleted") |
||||
|
.ValueGeneratedOnAdd() |
||||
|
.HasColumnName("IsDeleted") |
||||
|
.HasDefaultValue(false); |
||||
|
|
||||
|
b.Property<DateTime?>("LastModificationTime") |
||||
|
.HasColumnName("LastModificationTime"); |
||||
|
|
||||
|
b.Property<Guid?>("LastModifierId") |
||||
|
.HasColumnName("LastModifierId"); |
||||
|
|
||||
|
b.Property<string>("Name") |
||||
|
.IsRequired() |
||||
|
.HasColumnName("Name") |
||||
|
.HasMaxLength(64); |
||||
|
|
||||
|
b.Property<int>("UsageCount") |
||||
|
.HasColumnName("UsageCount"); |
||||
|
|
||||
|
b.HasKey("Id"); |
||||
|
|
||||
|
b.ToTable("BlgTags"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityRole") |
||||
|
.WithMany("Claims") |
||||
|
.HasForeignKey("RoleId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser") |
||||
|
.WithMany("Claims") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser") |
||||
|
.WithMany("Logins") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityRole") |
||||
|
.WithMany() |
||||
|
.HasForeignKey("RoleId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
|
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser") |
||||
|
.WithMany("Roles") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Abp.Identity.IdentityUser") |
||||
|
.WithMany("Tokens") |
||||
|
.HasForeignKey("UserId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Comments.Comment", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Blogging.Posts.Post") |
||||
|
.WithMany() |
||||
|
.HasForeignKey("PostId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
|
||||
|
b.HasOne("Volo.Blogging.Comments.Comment") |
||||
|
.WithMany() |
||||
|
.HasForeignKey("RepliedCommentId"); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Posts.Post", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Blogging.Blogs.Blog") |
||||
|
.WithMany() |
||||
|
.HasForeignKey("BlogId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
}); |
||||
|
|
||||
|
modelBuilder.Entity("Volo.Blogging.Posts.PostTag", b => |
||||
|
{ |
||||
|
b.HasOne("Volo.Blogging.Posts.Post") |
||||
|
.WithMany("Tags") |
||||
|
.HasForeignKey("PostId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
|
||||
|
b.HasOne("Volo.Blogging.Tagging.Tag") |
||||
|
.WithMany() |
||||
|
.HasForeignKey("TagId") |
||||
|
.OnDelete(DeleteBehavior.Cascade); |
||||
|
}); |
||||
|
#pragma warning restore 612, 618
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
|
||||
|
namespace Volo.BloggingTestApp.EntityFrameworkCore.Migrations |
||||
|
{ |
||||
|
public partial class added_CoverImage : Migration |
||||
|
{ |
||||
|
protected override void Up(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.AddColumn<string>( |
||||
|
name: "CoverImage", |
||||
|
table: "BlgPosts", |
||||
|
nullable: false, |
||||
|
defaultValue: ""); |
||||
|
} |
||||
|
|
||||
|
protected override void Down(MigrationBuilder migrationBuilder) |
||||
|
{ |
||||
|
migrationBuilder.DropColumn( |
||||
|
name: "CoverImage", |
||||
|
table: "BlgPosts"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,31 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Microsoft.AspNetCore.Mvc; |
||||
|
using Volo.Abp.AspNetCore.Mvc; |
||||
|
using Volo.Blogging.Areas.Blog.Models; |
||||
|
using Volo.Blogging.Hosting; |
||||
|
|
||||
|
namespace Volo.Blogging.Areas.Blog.Controllers |
||||
|
{ |
||||
|
[Area("Blog")] |
||||
|
[Route("Blog/[controller]/[action]")]
|
||||
|
public class FilesController : AbpController |
||||
|
{ |
||||
|
private readonly IFileService _fileService; |
||||
|
|
||||
|
public FilesController(IFileService fileService) |
||||
|
{ |
||||
|
_fileService = fileService; |
||||
|
} |
||||
|
|
||||
|
[HttpPost] |
||||
|
public async Task<JsonResult> UploadImage(IFormFile file) |
||||
|
{ |
||||
|
file.ValidateImage(out var fileBytes); |
||||
|
|
||||
|
var fileUrl = await _fileService.SaveFileAsync(fileBytes, file.FileName); |
||||
|
|
||||
|
return Json(new FileUploadResult(fileUrl)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.IO; |
||||
|
|
||||
|
namespace Volo.Blogging.Areas.Blog.Helpers |
||||
|
{ |
||||
|
public class ImageFormatHelper |
||||
|
{ |
||||
|
public static ImageFormat GetImageRawFormat(byte[] fileBytes) |
||||
|
{ |
||||
|
using (var memoryStream = new MemoryStream(fileBytes)) |
||||
|
{ |
||||
|
return System.Drawing.Image.FromStream(memoryStream).RawFormat; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static bool IsValidImage(byte[] fileBytes, ICollection<ImageFormat> validFormats) |
||||
|
{ |
||||
|
var imageFormat = GetImageRawFormat(fileBytes); |
||||
|
return validFormats.Contains(imageFormat); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
namespace Volo.Blogging.Areas.Blog.Models |
||||
|
{ |
||||
|
public class FileUploadResult |
||||
|
{ |
||||
|
public string FileUrl { get; set; } |
||||
|
|
||||
|
public FileUploadResult(string fileUrl) |
||||
|
{ |
||||
|
FileUrl = fileUrl; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Drawing.Imaging; |
||||
|
using System.Linq; |
||||
|
|
||||
|
namespace Volo.Blogging |
||||
|
{ |
||||
|
public class BloggingWebConsts |
||||
|
{ |
||||
|
public class FileUploading |
||||
|
{ |
||||
|
public const string DefaultFileUploadFolderName = "files"; |
||||
|
|
||||
|
public static readonly ICollection<ImageFormat> AllowedImageUploadFormats = new Collection<ImageFormat> |
||||
|
{ |
||||
|
ImageFormat.Jpeg, |
||||
|
ImageFormat.Png, |
||||
|
ImageFormat.Gif, |
||||
|
ImageFormat.Bmp |
||||
|
}; |
||||
|
|
||||
|
public static string AllowedImageFormatsJoint => string.Join(",", AllowedImageUploadFormats.Select(x => x.ToString())); |
||||
|
|
||||
|
public const int MaxFileSize = 5242880; //5MB
|
||||
|
|
||||
|
public static int MaxFileSizeAsMegabytes => Convert.ToInt32((MaxFileSize / 1024f) / 1024f); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,72 @@ |
|||||
|
using System.IO; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Hosting; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Guids; |
||||
|
|
||||
|
namespace Volo.Blogging.Hosting |
||||
|
{ |
||||
|
public class FileService : IFileService, ITransientDependency |
||||
|
{ |
||||
|
private readonly IHostingEnvironment _hostingEnvironment; |
||||
|
private readonly IGuidGenerator _guidGenerator; |
||||
|
|
||||
|
public FileService(IHostingEnvironment hostingEnvironment, IGuidGenerator guidGenerator) |
||||
|
{ |
||||
|
_hostingEnvironment = hostingEnvironment; |
||||
|
_guidGenerator = guidGenerator; |
||||
|
} |
||||
|
|
||||
|
public string FileUploadDirectory |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
var uploadDirectory = Path.Combine(_hostingEnvironment.WebRootPath, BloggingWebConsts.FileUploading.DefaultFileUploadFolderName); |
||||
|
if (!Directory.Exists(uploadDirectory)) |
||||
|
{ |
||||
|
Directory.CreateDirectory(uploadDirectory); |
||||
|
} |
||||
|
|
||||
|
return uploadDirectory; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public string GenerateUniqueFileName(string extension, string prefix = null, string postfix = null) |
||||
|
{ |
||||
|
return prefix + _guidGenerator.Create().ToString("N") + postfix + extension; |
||||
|
} |
||||
|
|
||||
|
public async Task<string> SaveFormFileAndGetUrlAsync(IFormFile file) |
||||
|
{ |
||||
|
var uniqueFileName = await SaveFileInternalAsync(file.FileName, file.AsBytes()); |
||||
|
return GetFileUrl(uniqueFileName); |
||||
|
} |
||||
|
|
||||
|
public async Task<string> SaveFileAsync(byte[] fileBytes, string originalFileName) |
||||
|
{ |
||||
|
if (fileBytes == null || fileBytes.Length == 0) |
||||
|
{ |
||||
|
throw new UserFriendlyException("File is empty!"); |
||||
|
} |
||||
|
|
||||
|
var uniqueFileName = await SaveFileInternalAsync(originalFileName, fileBytes); |
||||
|
return GetFileUrl(uniqueFileName); |
||||
|
} |
||||
|
|
||||
|
private static string GetFileUrl(string uniqueFileName) |
||||
|
{ |
||||
|
return "/" + BloggingWebConsts.FileUploading.DefaultFileUploadFolderName + "/" + uniqueFileName; |
||||
|
} |
||||
|
|
||||
|
private async Task<string> SaveFileInternalAsync(string originalFileName, byte[] fileBytes) |
||||
|
{ |
||||
|
var uniqueFileName = GenerateUniqueFileName(Path.GetExtension(originalFileName)); |
||||
|
var filePath = Path.Combine(FileUploadDirectory, uniqueFileName); |
||||
|
File.WriteAllBytes(filePath, fileBytes); //TODO: Previously was using WriteAllBytesAsync, but it's only in .netcore.
|
||||
|
return uniqueFileName; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
using System.IO; |
||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Blogging.Areas.Blog.Helpers; |
||||
|
|
||||
|
namespace Volo.Blogging.Hosting |
||||
|
{ |
||||
|
public static class FormFileExtensions |
||||
|
{ |
||||
|
public static byte[] AsBytes(this IFormFile file) |
||||
|
{ |
||||
|
byte[] fileBytes; |
||||
|
using (var stream = file.OpenReadStream()) |
||||
|
{ |
||||
|
fileBytes = stream.GetAllBytes(); |
||||
|
} |
||||
|
|
||||
|
return fileBytes; |
||||
|
} |
||||
|
|
||||
|
public static void ValidateImage([CanBeNull] this IFormFile file, out byte[] fileBytes) |
||||
|
{ |
||||
|
fileBytes = null; |
||||
|
|
||||
|
if (file == null) |
||||
|
{ |
||||
|
throw new UserFriendlyException("No file found!"); |
||||
|
} |
||||
|
|
||||
|
if (file.Length <= 0) |
||||
|
{ |
||||
|
throw new UserFriendlyException("File is empty!"); |
||||
|
} |
||||
|
|
||||
|
if (!file.ContentType.Contains("image")) |
||||
|
{ |
||||
|
throw new UserFriendlyException("Not a valid image!"); |
||||
|
} |
||||
|
|
||||
|
using (var stream = file.OpenReadStream()) |
||||
|
{ |
||||
|
fileBytes = stream.GetAllBytes(); |
||||
|
} |
||||
|
|
||||
|
if (!ImageFormatHelper.IsValidImage(fileBytes, BloggingWebConsts.FileUploading.AllowedImageUploadFormats)) |
||||
|
{ |
||||
|
throw new UserFriendlyException("Not a valid image format!"); |
||||
|
} |
||||
|
|
||||
|
if (file.Length > BloggingWebConsts.FileUploading.MaxFileSize) |
||||
|
{ |
||||
|
throw new UserFriendlyException($"File exceeds the maximum upload size ({BloggingWebConsts.FileUploading.MaxFileSizeAsMegabytes} MB)!"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.AspNetCore.Http; |
||||
|
|
||||
|
namespace Volo.Blogging.Hosting |
||||
|
{ |
||||
|
public interface IFileService |
||||
|
{ |
||||
|
string FileUploadDirectory { get; } |
||||
|
|
||||
|
string GenerateUniqueFileName(string extension, string prefix = null, string postfix = null); |
||||
|
|
||||
|
Task<string> SaveFormFileAndGetUrlAsync(IFormFile file); |
||||
|
|
||||
|
Task<string> SaveFileAsync(byte[] fileBytes, string originalFileName); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue