first commit
This commit is contained in:
parent
8147e29185
commit
c70d7501e9
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
.vscode/
|
||||||
|
*.db
|
||||||
|
saves
|
||||||
|
|
87
Controllers/FileController.cs
Normal file
87
Controllers/FileController.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using StorageServer.IO;
|
||||||
|
using StorageServer.Models;
|
||||||
|
using StorageServer.Models.Request;
|
||||||
|
using StorageServer.Models.Response;
|
||||||
|
|
||||||
|
namespace StorageServer.Controllers;
|
||||||
|
|
||||||
|
public class FileController : Controller
|
||||||
|
{
|
||||||
|
private readonly DatabaseFactory database;
|
||||||
|
private readonly StorageProvider provider;
|
||||||
|
|
||||||
|
public FileController(DatabaseFactory database, StorageProvider provider) {
|
||||||
|
this.database = database;
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[DisableRequestSizeLimit]
|
||||||
|
public async Task<IActionResult> Create(FileCreateModel model) {
|
||||||
|
if (!ModelState.IsValid) {
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.File is null || string.IsNullOrWhiteSpace(model.File.ContentType)) {
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
using (TempFile tempFile = new TempFile()) {
|
||||||
|
string fileName = string.IsNullOrWhiteSpace(model.FileName) ? model.File.FileName : model.FileName;
|
||||||
|
FileModel fileModel = new FileModel() {
|
||||||
|
FileName = fileName,
|
||||||
|
MimeType = model.File.ContentType,
|
||||||
|
CreatedAt = DateTime.Now,
|
||||||
|
};
|
||||||
|
|
||||||
|
using (FileStream fs = tempFile.Open()) {
|
||||||
|
await model.File.CopyToAsync(fs);
|
||||||
|
fs.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
string hash = await this.provider.ComputeStreamHash(fs);
|
||||||
|
fileModel.HashValue = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
long fileId = this.database.Create(fileModel);
|
||||||
|
fileModel.FileID = fileId;
|
||||||
|
|
||||||
|
using (FileStream fs = tempFile.Open()) {
|
||||||
|
await this.provider.SaveFile(fileModel, fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Json(new FileCreateResponseModel() {
|
||||||
|
FileId = fileId,
|
||||||
|
FileName = fileName,
|
||||||
|
MimeType = fileModel.MimeType,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (Exception) {
|
||||||
|
return Problem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult Read(FileReadModel model) {
|
||||||
|
if (!ModelState.IsValid) {
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileModel fileModel = this.database.Read(model.FileID);
|
||||||
|
if (fileModel is null) {
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream stream = this.provider.GetFile(fileModel);
|
||||||
|
this.HttpContext.Response.RegisterForDispose(stream);
|
||||||
|
|
||||||
|
return File(stream, fileModel.MimeType, fileModel.FileName, true);
|
||||||
|
} catch (FileNotFoundException) {
|
||||||
|
return NotFound();
|
||||||
|
} catch (Exception) {
|
||||||
|
return Problem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
Controllers/FileListController.cs
Normal file
40
Controllers/FileListController.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using StorageServer.IO;
|
||||||
|
using StorageServer.Models;
|
||||||
|
using StorageServer.Models.Request;
|
||||||
|
using StorageServer.Models.Response;
|
||||||
|
|
||||||
|
namespace StorageServer.Controllers;
|
||||||
|
|
||||||
|
public class FileListController : Controller
|
||||||
|
{
|
||||||
|
private readonly DatabaseFactory database;
|
||||||
|
public FileListController(DatabaseFactory database) {
|
||||||
|
this.database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Read(FileListReadModel model) {
|
||||||
|
if (!ModelState.IsValid) {
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.Page < 0) {
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
IEnumerable<FileModel> fileModels = this.database.ReadAll();
|
||||||
|
int readCount = 100;
|
||||||
|
IEnumerable<FileModel> seekedModels = fileModels.Skip(readCount * model.Page).Take(readCount);
|
||||||
|
|
||||||
|
List<FileListResponseModel> fileLists = new List<FileListResponseModel>();
|
||||||
|
foreach (FileModel fileModel in seekedModels) {
|
||||||
|
fileLists.Add(new FileListResponseModel(fileModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Json(fileLists);
|
||||||
|
} catch (Exception) {
|
||||||
|
return Problem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
IO/DatabaseFactory.cs
Normal file
35
IO/DatabaseFactory.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
namespace StorageServer.IO;
|
||||||
|
|
||||||
|
using StorageServer.Models;
|
||||||
|
|
||||||
|
public class DatabaseFactory : IDisposable {
|
||||||
|
private IDatabase database;
|
||||||
|
|
||||||
|
public DatabaseFactory(string fileName) {
|
||||||
|
this.database = new FileDatabase(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
this.database.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Create(FileModel model) {
|
||||||
|
return this.database.Insert<FileModel>(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileModel Read(long id) {
|
||||||
|
return this.database.Select<FileModel>(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<FileModel> ReadAll() {
|
||||||
|
return this.database.SelectAll<FileModel>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Update(FileModel model) {
|
||||||
|
return this.database.Update<FileModel>(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(long id) {
|
||||||
|
return this.database.Delete(id);
|
||||||
|
}
|
||||||
|
}
|
77
IO/FileDatabase.cs
Normal file
77
IO/FileDatabase.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
using LiteDB;
|
||||||
|
|
||||||
|
namespace StorageServer.IO;
|
||||||
|
|
||||||
|
public class FileDatabase : IDatabase
|
||||||
|
{
|
||||||
|
private LiteDatabase liteDatabase;
|
||||||
|
private const string tableName = "files";
|
||||||
|
|
||||||
|
public FileDatabase(string fileName) {
|
||||||
|
this.liteDatabase = new LiteDatabase(new ConnectionString() {
|
||||||
|
Filename = fileName,
|
||||||
|
Connection = ConnectionType.Direct,
|
||||||
|
}, new() {
|
||||||
|
EnumAsInteger = true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
this.liteDatabase.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Count()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return this.liteDatabase.GetCollection(tableName).LongCount();
|
||||||
|
} catch (LiteException e) {
|
||||||
|
throw new IOException(e.Message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Delete(long id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return this.liteDatabase.GetCollection(tableName).Delete(id);
|
||||||
|
} catch (LiteException e) {
|
||||||
|
throw new IOException(e.Message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Insert<T>(T model)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return this.liteDatabase.GetCollection<T>(tableName).Insert(model);
|
||||||
|
} catch (LiteException e) {
|
||||||
|
throw new IOException(e.Message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Select<T>(long id)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return this.liteDatabase.GetCollection<T>(tableName).FindById(id);
|
||||||
|
} catch (LiteException e) {
|
||||||
|
throw new IOException(e.Message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<T> SelectAll<T>()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return this.liteDatabase.GetCollection<T>(tableName).FindAll();
|
||||||
|
} catch (LiteException e) {
|
||||||
|
throw new IOException(e.Message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Update<T>(T model)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return this.liteDatabase.GetCollection<T>(tableName).Update(model);
|
||||||
|
} catch (LiteException e) {
|
||||||
|
throw new IOException(e.Message, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
IO/IDatabase.cs
Normal file
11
IO/IDatabase.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace StorageServer.IO;
|
||||||
|
|
||||||
|
public interface IDatabase : IDisposable {
|
||||||
|
public IEnumerable<T> SelectAll<T>();
|
||||||
|
public T Select<T>(long id);
|
||||||
|
public long Insert<T>(T model);
|
||||||
|
public bool Update<T>(T model);
|
||||||
|
public bool Delete(long id);
|
||||||
|
|
||||||
|
public long Count();
|
||||||
|
}
|
44
IO/StorageProvider.cs
Normal file
44
IO/StorageProvider.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using System.Security.Cryptography;
|
||||||
|
using StorageServer.Models;
|
||||||
|
|
||||||
|
namespace StorageServer.IO;
|
||||||
|
|
||||||
|
public class StorageProvider {
|
||||||
|
public static int BufferSize = 16384;
|
||||||
|
|
||||||
|
private string saveDirectory;
|
||||||
|
|
||||||
|
public StorageProvider(string saveDirectory) {
|
||||||
|
this.saveDirectory = saveDirectory;
|
||||||
|
if (!Directory.Exists(saveDirectory)) {
|
||||||
|
Directory.CreateDirectory(saveDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> ComputeStreamHash(Stream stream) {
|
||||||
|
using (Stream buffered = new BufferedStream(stream, BufferSize)) {
|
||||||
|
byte[] checksum = await SHA256.HashDataAsync(buffered);
|
||||||
|
return BitConverter.ToString(checksum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SaveFile(FileModel fileModel, FileStream fs) {
|
||||||
|
string extension = Path.GetExtension(fileModel.FileName);
|
||||||
|
string saveFileName = string.Format("{0}{1}", fileModel.FileID, extension);
|
||||||
|
string saveFullName = Path.Combine(this.saveDirectory, saveFileName);
|
||||||
|
using (FileStream dest = new FileStream(saveFullName, FileMode.OpenOrCreate)) {
|
||||||
|
await fs.CopyToAsync(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream GetFile(FileModel fileModel) {
|
||||||
|
string extension = Path.GetExtension(fileModel.FileName);
|
||||||
|
string saveFileName = string.Format("{0}{1}", fileModel.FileID, extension);
|
||||||
|
string saveFullName = Path.Combine(this.saveDirectory, saveFileName);
|
||||||
|
if (!File.Exists(saveFullName)) {
|
||||||
|
throw new FileNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FileStream(saveFullName, FileMode.Open);
|
||||||
|
}
|
||||||
|
}
|
26
IO/TempFile.cs
Normal file
26
IO/TempFile.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
namespace StorageServer.IO;
|
||||||
|
|
||||||
|
public class TempFile : IDisposable {
|
||||||
|
public string FileName { get; }
|
||||||
|
public TempFile() {
|
||||||
|
this.FileName = Path.GetTempFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileStream Open() {
|
||||||
|
return new FileStream(this.FileName, FileMode.Open);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<FileStream> CopyToAsync(Stream stream) {
|
||||||
|
FileStream fs = this.Open();
|
||||||
|
await fs.CopyToAsync(stream);
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() {
|
||||||
|
try {
|
||||||
|
File.Delete(this.FileName);
|
||||||
|
} catch (Exception) {
|
||||||
|
// unhandled exception error.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
IO/XmlReader.cs
Normal file
29
IO/XmlReader.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace StorageServer.IO;
|
||||||
|
|
||||||
|
public static class XmlReader {
|
||||||
|
public static void Save<T>(string filePath, T obj) {
|
||||||
|
try {
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(T));
|
||||||
|
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate)) {
|
||||||
|
serializer.Serialize(fs, obj);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine($"Error: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T Read<T>(string filePath) {
|
||||||
|
try {
|
||||||
|
XmlSerializer serializer = new XmlSerializer(typeof(T));
|
||||||
|
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate)) {
|
||||||
|
return (T) serializer.Deserialize(fs);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine($"Error: {e.Message}");
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
13
Models/FileModel.cs
Normal file
13
Models/FileModel.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using LiteDB;
|
||||||
|
|
||||||
|
namespace StorageServer.Models;
|
||||||
|
|
||||||
|
public class FileModel {
|
||||||
|
[BsonId]
|
||||||
|
public long FileID { get; set; }
|
||||||
|
|
||||||
|
public string FileName { get; set; }
|
||||||
|
public string MimeType { get; set; }
|
||||||
|
public string HashValue { get; set; }
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
}
|
9
Models/Request/FileCreateModel.cs
Normal file
9
Models/Request/FileCreateModel.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace StorageServer.Models.Request;
|
||||||
|
|
||||||
|
public class FileCreateModel {
|
||||||
|
[Required]
|
||||||
|
public IFormFile File { get; set; }
|
||||||
|
public string FileName { get; set; }
|
||||||
|
}
|
5
Models/Request/FileListReadModel.cs
Normal file
5
Models/Request/FileListReadModel.cs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
namespace StorageServer.Models.Request;
|
||||||
|
|
||||||
|
public class FileListReadModel {
|
||||||
|
public int Page { get; set; } = 0;
|
||||||
|
}
|
8
Models/Request/FileReadModel.cs
Normal file
8
Models/Request/FileReadModel.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace StorageServer.Models.Request;
|
||||||
|
|
||||||
|
public class FileReadModel {
|
||||||
|
[Required]
|
||||||
|
public long FileID { get; set; }
|
||||||
|
}
|
7
Models/Response/FileCreateResponseModel.cs
Normal file
7
Models/Response/FileCreateResponseModel.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace StorageServer.Models.Response;
|
||||||
|
|
||||||
|
public class FileCreateResponseModel {
|
||||||
|
public long FileId { get; set; } = -1;
|
||||||
|
public string FileName { get; set; }
|
||||||
|
public string MimeType { get; set; }
|
||||||
|
}
|
20
Models/Response/FileListResponseModel.cs
Normal file
20
Models/Response/FileListResponseModel.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace StorageServer.Models.Response;
|
||||||
|
|
||||||
|
public class FileListResponseModel {
|
||||||
|
public FileListResponseModel() {}
|
||||||
|
public FileListResponseModel(FileModel model) {
|
||||||
|
this.FileID = model.FileID;
|
||||||
|
this.FileName = model.FileName;
|
||||||
|
this.MimeType = model.MimeType;
|
||||||
|
this.HashValue = model.HashValue;
|
||||||
|
this.CreatedAt = model.CreatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long FileID { get; set; }
|
||||||
|
|
||||||
|
public string FileName { get; set; }
|
||||||
|
public string MimeType { get; set; }
|
||||||
|
public string HashValue { get; set; }
|
||||||
|
public DateTime CreatedAt { get; set; }
|
||||||
|
|
||||||
|
}
|
6
Models/SettingModel.cs
Normal file
6
Models/SettingModel.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
namespace StorageServer.Models;
|
||||||
|
|
||||||
|
public class SettingModel {
|
||||||
|
public string DBFilePath { get; set; }
|
||||||
|
public string SavePath { get; set; }
|
||||||
|
}
|
65
Program.cs
Normal file
65
Program.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using StorageServer.IO;
|
||||||
|
using StorageServer.Models;
|
||||||
|
|
||||||
|
namespace StorageServer;
|
||||||
|
|
||||||
|
public class Program {
|
||||||
|
public static void Main(string[] args) {
|
||||||
|
const string settingPath = "storage_config.xml";
|
||||||
|
const string allowOrigins = "_storageserver_allow_origin";
|
||||||
|
if (!File.Exists(settingPath)) {
|
||||||
|
XmlReader.Save<SettingModel>(settingPath, new SettingModel() {
|
||||||
|
DBFilePath = "files.db",
|
||||||
|
SavePath = "saves",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingModel setting = XmlReader.Read<SettingModel>(settingPath);
|
||||||
|
|
||||||
|
DatabaseFactory factory = new DatabaseFactory(setting.DBFilePath);
|
||||||
|
StorageProvider provider = new StorageProvider(setting.SavePath);
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Services.AddSingleton(factory);
|
||||||
|
builder.Services.AddSingleton(provider);
|
||||||
|
// Add services to the container.
|
||||||
|
builder.Services.AddControllersWithViews();
|
||||||
|
|
||||||
|
builder.Services.AddCors(options => {
|
||||||
|
options.AddPolicy(allowOrigins, policy => {
|
||||||
|
policy.AllowAnyOrigin();
|
||||||
|
policy.AllowAnyHeader();
|
||||||
|
policy.AllowAnyMethod();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (!app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseExceptionHandler("/Home/Error");
|
||||||
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
|
app.UseHsts();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseCors(allowOrigins);
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllerRoute(
|
||||||
|
name: "default",
|
||||||
|
pattern: "{controller=File}/{action=Read}/{FileId?}");
|
||||||
|
|
||||||
|
app.Run();
|
||||||
|
|
||||||
|
factory.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
37
Properties/launchSettings.json
Normal file
37
Properties/launchSettings.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:38186",
|
||||||
|
"sslPort": 44352
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "http://localhost:5070",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"launchBrowser": true,
|
||||||
|
"applicationUrl": "https://localhost:7261;http://localhost:5070",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
StorageServer.csproj
Normal file
13
StorageServer.csproj
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<Nullable>disable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="LiteDB" Version="5.0.17" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
8
appsettings.Development.json
Normal file
8
appsettings.Development.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
appsettings.json
Normal file
9
appsettings.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
5
storage_config.xml
Normal file
5
storage_config.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<SettingModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<DBFilePath>files.db</DBFilePath>
|
||||||
|
<SavePath>saves</SavePath>
|
||||||
|
</SettingModel>
|
Loading…
Reference in New Issue
Block a user