diff --git a/ImageApi.Core/ImageParameter.cs b/ImageApi.Core/ImageParameter.cs
index 8568514..a6c5cbb 100644
--- a/ImageApi.Core/ImageParameter.cs
+++ b/ImageApi.Core/ImageParameter.cs
@@ -30,7 +30,7 @@ public ImageParameter GetFixed(IImageParameterFixer fixer)
public string GetRelativePath()
{
- var folder = $"App_Data\\storage\\images\\{this.Year}\\{this.Month}\\{this.Id}\\";
+ var folder = $"App_Data/storage/images/{this.Year}/{this.Month}/{this.Id}/";
if (this.ImageFormat == ImageFormat.Gif)
{
return folder + "Full.gif";
@@ -40,7 +40,7 @@ public string GetRelativePath()
public string GetVirtualPath()
{
- return "~\\"+GetRelativePath();
+ return "~/"+GetRelativePath();
}
}
}
diff --git a/ImageApi/Controllers/ImageController.cs b/ImageApi/Controllers/ImageController.cs
index 3e89194..72a42f7 100644
--- a/ImageApi/Controllers/ImageController.cs
+++ b/ImageApi/Controllers/ImageController.cs
@@ -7,6 +7,7 @@
using ImageCore;
using ImageCore.Enums;
using ImageCore.Extensions;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -51,7 +52,7 @@ public ImageController(IFileStore fileStore, IImageService imageService, ImageOp
///
[Route("/img/{size}/t{imageType}t{yearMonth}-{id}.{format}")]
[HttpGet]
- [ResponseCache(Duration = 600, Location = ResponseCacheLocation.Any)]
+ [ResponseCache(Duration = 600, Location = ResponseCacheLocation.Client)]
public async Task Index([FromServices] IImageParameterFixer parameterFixer,
[FromRoute] ImageParameter parameter)
{
@@ -93,6 +94,8 @@ public async Task Index([FromServices] IImageParameterFixer param
/// 例如 /img/s80x80/t20t201902-94E0437664E3FA99C094E0437664E3FA99C0.png
///
[HttpPost]
+ [Authorize]
+ [DisableRequestSizeLimit]
public async Task Upload([FromFile] ImageFileInfo file, bool isTemp = false,
BusinessType businessType = BusinessType.Default)
{
diff --git a/ImageApi/Dockerfile b/ImageApi/Dockerfile
index c52689d..86e47b7 100644
--- a/ImageApi/Dockerfile
+++ b/ImageApi/Dockerfile
@@ -1,15 +1,13 @@
-#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
-#For more information, please see https://aka.ms/containercompat
-
-FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803 AS base
+FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
-FROM microsoft/dotnet:2.2-sdk-nanoserver-1803 AS build
+FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY ["ImageApi/ImageApi.csproj", "ImageApi/"]
COPY ["ImageApi.Core/ImageApi.Core.csproj", "ImageApi.Core/"]
COPY ["ImageCore/ImageCore.csproj", "ImageCore/"]
+COPY ["Persistence/ImageCore.Persistence.EntityFramework/ImageCore.Persistence.EntityFramework.csproj", "Persistence/ImageCore.Persistence.EntityFramework/"]
RUN dotnet restore "ImageApi/ImageApi.csproj"
COPY . .
WORKDIR "/src/ImageApi"
diff --git a/ImageApi/Dockerfile1.original b/ImageApi/Dockerfile1.original
new file mode 100644
index 0000000..c52689d
--- /dev/null
+++ b/ImageApi/Dockerfile1.original
@@ -0,0 +1,24 @@
+#Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed.
+#For more information, please see https://aka.ms/containercompat
+
+FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803 AS base
+WORKDIR /app
+EXPOSE 80
+
+FROM microsoft/dotnet:2.2-sdk-nanoserver-1803 AS build
+WORKDIR /src
+COPY ["ImageApi/ImageApi.csproj", "ImageApi/"]
+COPY ["ImageApi.Core/ImageApi.Core.csproj", "ImageApi.Core/"]
+COPY ["ImageCore/ImageCore.csproj", "ImageCore/"]
+RUN dotnet restore "ImageApi/ImageApi.csproj"
+COPY . .
+WORKDIR "/src/ImageApi"
+RUN dotnet build "ImageApi.csproj" -c Release -o /app
+
+FROM build AS publish
+RUN dotnet publish "ImageApi.csproj" -c Release -o /app
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app .
+ENTRYPOINT ["dotnet", "ImageApi.dll"]
\ No newline at end of file
diff --git a/ImageApi/ImageApi.csproj b/ImageApi/ImageApi.csproj
index bf2c7f6..f3bc101 100644
--- a/ImageApi/ImageApi.csproj
+++ b/ImageApi/ImageApi.csproj
@@ -3,7 +3,7 @@
netcoreapp2.2
InProcess
- Windows
+ Linux
@@ -12,9 +12,12 @@
+
+
+
diff --git a/ImageApi/ImageFileInfoExtensions.cs b/ImageApi/ImageFileInfoExtensions.cs
index 9136e2c..b5c4a14 100644
--- a/ImageApi/ImageFileInfoExtensions.cs
+++ b/ImageApi/ImageFileInfoExtensions.cs
@@ -10,9 +10,10 @@ public static class ImageFileInfoExtensions
public static ImageDto ToImage(this ImageFileInfo fileInfo)
{
ImageFormat imageFormat;
- switch (fileInfo.Extension)
+ switch (fileInfo.Extension.ToLower())
{
case ".jpg":
+ case ".jpeg":
imageFormat = ImageFormat.Jpeg;
break;
case ".gif":
diff --git a/ImageApi/Program.cs b/ImageApi/Program.cs
index a743a1f..65862ca 100644
--- a/ImageApi/Program.cs
+++ b/ImageApi/Program.cs
@@ -19,6 +19,8 @@ public static void Main(string[] args)
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
+ .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseUrls("http://*:8089")
.UseStartup();
}
}
diff --git a/ImageApi/Properties/PublishProfiles/FolderProfile.pubxml b/ImageApi/Properties/PublishProfiles/FolderProfile.pubxml
index 2500033..031a5e7 100644
--- a/ImageApi/Properties/PublishProfiles/FolderProfile.pubxml
+++ b/ImageApi/Properties/PublishProfiles/FolderProfile.pubxml
@@ -15,5 +15,8 @@
2528c869-0822-49b2-ba00-6beebc316244
D:\wwwroot\ImageService
False
+ netcoreapp2.2
+ false
+ <_IsPortable>true
\ No newline at end of file
diff --git a/ImageApi/Properties/PublishProfiles/FolderProfile1.pubxml b/ImageApi/Properties/PublishProfiles/FolderProfile1.pubxml
new file mode 100644
index 0000000..444f409
--- /dev/null
+++ b/ImageApi/Properties/PublishProfiles/FolderProfile1.pubxml
@@ -0,0 +1,22 @@
+
+
+
+
+ FileSystem
+ FileSystem
+ Release
+ Any CPU
+
+ True
+ False
+ netcoreapp2.2
+ 2528c869-0822-49b2-ba00-6beebc316244
+ false
+ <_IsPortable>true
+ D:\wwwroot\ImageService_Demo
+ False
+
+
\ No newline at end of file
diff --git a/ImageApi/Properties/PublishProfiles/FolderProfile2.pubxml b/ImageApi/Properties/PublishProfiles/FolderProfile2.pubxml
new file mode 100644
index 0000000..8b70de7
--- /dev/null
+++ b/ImageApi/Properties/PublishProfiles/FolderProfile2.pubxml
@@ -0,0 +1,19 @@
+
+
+
+
+ FileSystem
+ FileSystem
+ Release
+ Any CPU
+
+ True
+ False
+ 2528c869-0822-49b2-ba00-6beebc316244
+ D:\wwwroot\ImageServer_Mysql
+ False
+
+
\ No newline at end of file
diff --git a/ImageApi/Startup.cs b/ImageApi/Startup.cs
index fe2eacd..7c20f5d 100644
--- a/ImageApi/Startup.cs
+++ b/ImageApi/Startup.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -22,13 +23,13 @@ public class Startup
{
private const string DefaultCorsPolicyName = "public";
- private readonly IConfigurationRoot _appConfiguration;
+ private readonly IConfiguration configuration;
private readonly IHostingEnvironment _hostingEnvironment;
- public Startup(IHostingEnvironment env)
+ public Startup(IHostingEnvironment env, IConfiguration configuration)
{
_hostingEnvironment = env;
- _appConfiguration = env.GetAppConfiguration();
+ this.configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
@@ -39,13 +40,30 @@ public void ConfigureServices(IServiceCollection services)
services.AddSingleton(
new PhysicalFileProvider(Directory.GetCurrentDirectory()));
services.AddSingleton();
+ services.AddEntityFrameworkNpgsql();
+ services.AddAuthentication("Bearer")
+ .AddIdentityServerAuthentication(options =>
+ {
+ options.Authority = configuration["AuthServer:Authority"];
+ options.RequireHttpsMetadata = false;
+ options.ApiName = configuration["AuthServer:ApiName"];
+ //options.InboundJwtClaimTypeMap["sub"] = AbpClaimTypes.UserId;
+ //options.InboundJwtClaimTypeMap["role"] = AbpClaimTypes.Role;
+ //options.InboundJwtClaimTypeMap["email"] = AbpClaimTypes.Email;
+ //options.InboundJwtClaimTypeMap["email_verified"] = AbpClaimTypes.EmailVerified;
+ //options.InboundJwtClaimTypeMap["phone_number"] = AbpClaimTypes.PhoneNumber;
+ //options.InboundJwtClaimTypeMap["phone_number_verified"] = AbpClaimTypes.PhoneNumberVerified;
+ //options.InboundJwtClaimTypeMap["name"] = AbpClaimTypes.UserName;
+ });
services.AddImageService(option =>
{
- option.Filters = new[] {".jpg", ".png", ".bmp"};
+ option.Filters = new[] {".jpg", ".jpeg", ".gif", ".png", ".bmp"};
})
.UseEntityFrameworkStore(builder =>
{
- builder.UseSqlServer("Server=localhost; Database=ImageDb; Trusted_Connection=True;");
+ //builder.UseSqlServer("Server=localhost; Database=ImageDb; Trusted_Connection=True;");
+ builder.UseNpgsql(configuration.GetConnectionString("Default"));
+ //builder.UseMySql(configuration.GetConnectionString("Mysql"));
});
services.AddCors(options =>
{
@@ -53,7 +71,7 @@ public void ConfigureServices(IServiceCollection services)
{
builder
.WithOrigins(
- _appConfiguration["CorsOrigins"]
+ configuration["CorsOrigins"]
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.ToArray()
)
@@ -68,6 +86,15 @@ public void ConfigureServices(IServiceCollection services)
c.SwaggerDoc("v1", new Info {Title = "图片资源API", Version = "v1"});
c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "ImageApi.xml"));
c.OperationFilter();
+ c.AddSecurityDefinition("bearerAuth", new ApiKeyScheme()
+ {
+ Description = "JWT Authorization header using the bearer scheme. Example: \"Authorization: Bearer {token}\"",
+ Name = "Authorization",
+ In = "header",
+ Type = "apiKey"
+ });
+ var security = new Dictionary> { { "bearerAuth", new string[] { } }, };
+ c.AddSecurityRequirement(security);
});
}
@@ -79,17 +106,10 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
app.UseDeveloperExceptionPage();
}
app.UseCors(DefaultCorsPolicyName);
+ app.UseAuthentication();
app.UseMvcWithDefaultRoute();
app.UseSwagger()
.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "图片资源API"); });
}
}
-
- public static class HostingEnvironmentExtensions
- {
- public static IConfigurationRoot GetAppConfiguration(this IHostingEnvironment env)
- {
- return AppConfigurations.Get(env.ContentRootPath, env.EnvironmentName);
- }
- }
}
diff --git a/ImageApi/SwaggerFileUploadFilter.cs b/ImageApi/SwaggerFileUploadFilter.cs
index c287c39..90006cb 100644
--- a/ImageApi/SwaggerFileUploadFilter.cs
+++ b/ImageApi/SwaggerFileUploadFilter.cs
@@ -20,9 +20,10 @@ public void Apply(Operation operation, OperationFilterContext context)
}
var fileParameters = context.ApiDescription.ActionDescriptor.Parameters
- .Where(n => n.ParameterType == typeof(IFormFile)||n.BindingInfo.BindingSource == BindingSource.FormFile).ToList();
+ .Where(n => n.ParameterType == typeof(IFormFile) ||
+ (n.BindingInfo != null && n.BindingInfo.BindingSource == BindingSource.FormFile)).ToList();
- if (fileParameters.Count < 0)
+ if (fileParameters.Count == 0)
{
return;
}
diff --git a/ImageApi/appsettings.json b/ImageApi/appsettings.json
index 9c898f8..3d03031 100644
--- a/ImageApi/appsettings.json
+++ b/ImageApi/appsettings.json
@@ -1,4 +1,11 @@
{
+ "ConnectionStrings": {
+ "Default": "host=6.6.6.6;port=5432;database=image;userid=postgres;pwd=123123;"
+ },
+ "AuthServer": {
+ "Authority": "http://localhost:44305/",
+ "ApiName": "Image"
+ },
"Logging": {
"LogLevel": {
"Default": "Warning"
diff --git a/ImageCore/ImageOption.cs b/ImageCore/ImageOption.cs
index 3265512..1d4d3aa 100644
--- a/ImageCore/ImageOption.cs
+++ b/ImageCore/ImageOption.cs
@@ -12,9 +12,9 @@ public class ImageOption
public string[] Filters { get; set; } = {".jpg", ".png", ".bmp"};
///
- /// 可接收文件最大的大小单位kb,默认为2MB
+ /// 可接收文件最大的大小单位kb,默认为5MB
///
- public long MaxContentLength { get; set; } = 1024*1024 * 2;
+ public long MaxContentLength { get; set; } = 1024*1024 * 5;
///
/// 文件存储模式,默认为分布式存储
diff --git a/Persistence/ImageCore.Persistence.EntityFramework/ImageCore.Persistence.EntityFramework.csproj b/Persistence/ImageCore.Persistence.EntityFramework/ImageCore.Persistence.EntityFramework.csproj
index 12b9d5b..63b61f7 100644
--- a/Persistence/ImageCore.Persistence.EntityFramework/ImageCore.Persistence.EntityFramework.csproj
+++ b/Persistence/ImageCore.Persistence.EntityFramework/ImageCore.Persistence.EntityFramework.csproj
@@ -8,6 +8,8 @@
+
+
diff --git a/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190301113830_Inital.Designer.cs b/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190426035517_initial.Designer.cs
similarity index 83%
rename from Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190301113830_Inital.Designer.cs
rename to Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190426035517_initial.Designer.cs
index f011f2b..ae6af73 100644
--- a/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190301113830_Inital.Designer.cs
+++ b/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190426035517_initial.Designer.cs
@@ -3,23 +3,23 @@
using ImageCore.Persistence.EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace ImageCore.Persistence.EntityFramework.Migrations
{
[DbContext(typeof(ImageDbContext))]
- [Migration("20190301113830_Inital")]
- partial class Inital
+ [Migration("20190426035517_initial")]
+ partial class initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
+ .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.2-servicing-10034")
- .HasAnnotation("Relational:MaxIdentifierLength", 128)
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ImageCore.Persistence.EntityFramework.Image", b =>
{
@@ -52,8 +52,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
b.HasKey("Id");
b.HasIndex("Key")
- .IsUnique()
- .HasFilter("[Key] IS NOT NULL");
+ .IsUnique();
b.ToTable("Images");
});
diff --git a/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190301113830_Inital.cs b/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190426035517_initial.cs
similarity index 92%
rename from Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190301113830_Inital.cs
rename to Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190426035517_initial.cs
index 109f587..48f532d 100644
--- a/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190301113830_Inital.cs
+++ b/Persistence/ImageCore.Persistence.EntityFramework/Migrations/20190426035517_initial.cs
@@ -3,7 +3,7 @@
namespace ImageCore.Persistence.EntityFramework.Migrations
{
- public partial class Inital : Migration
+ public partial class initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
@@ -32,8 +32,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
name: "IX_Images_Key",
table: "Images",
column: "Key",
- unique: true,
- filter: "[Key] IS NOT NULL");
+ unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
diff --git a/Persistence/ImageCore.Persistence.EntityFramework/Migrations/ImageDbContextModelSnapshot.cs b/Persistence/ImageCore.Persistence.EntityFramework/Migrations/ImageDbContextModelSnapshot.cs
index 19693ae..3dfff7c 100644
--- a/Persistence/ImageCore.Persistence.EntityFramework/Migrations/ImageDbContextModelSnapshot.cs
+++ b/Persistence/ImageCore.Persistence.EntityFramework/Migrations/ImageDbContextModelSnapshot.cs
@@ -3,8 +3,8 @@
using ImageCore.Persistence.EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace ImageCore.Persistence.EntityFramework.Migrations
{
@@ -15,9 +15,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
+ .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.2-servicing-10034")
- .HasAnnotation("Relational:MaxIdentifierLength", 128)
- .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ImageCore.Persistence.EntityFramework.Image", b =>
{
@@ -50,8 +50,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.HasKey("Id");
b.HasIndex("Key")
- .IsUnique()
- .HasFilter("[Key] IS NOT NULL");
+ .IsUnique();
b.ToTable("Images");
});