Add: Test-Client
This commit is contained in:
parent
c70d7501e9
commit
89d7d4592e
@ -62,6 +62,24 @@ public class FileController : Controller
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult ReadInfo(FileReadModel model) {
|
||||
if (!ModelState.IsValid) {
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
try {
|
||||
FileModel fileModel = this.database.Read(model.FileID);
|
||||
if (fileModel is null) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return Json(fileModel);
|
||||
} catch (Exception) {
|
||||
return Problem();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Read(FileReadModel model) {
|
||||
if (!ModelState.IsValid) {
|
||||
@ -84,4 +102,26 @@ public class FileController : Controller
|
||||
return Problem();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Delete(FileDeleteModel model) {
|
||||
if (!ModelState.IsValid) {
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
try {
|
||||
FileModel fileModel = this.database.Read(model.FileID);
|
||||
if (fileModel is null) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
this.provider.DeleteFile(fileModel);
|
||||
|
||||
return Ok();
|
||||
} catch (FileNotFoundException) {
|
||||
return NotFound();
|
||||
} catch (Exception) {
|
||||
return Problem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,22 +23,34 @@ public class StorageProvider {
|
||||
}
|
||||
|
||||
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);
|
||||
string saveFullName = GetFullPath(fileModel);
|
||||
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);
|
||||
string saveFullName = GetFullPath(fileModel);
|
||||
if (!File.Exists(saveFullName)) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
return new FileStream(saveFullName, FileMode.Open);
|
||||
}
|
||||
|
||||
public void DeleteFile(FileModel fileModel) {
|
||||
string saveFullName = GetFullPath(fileModel);
|
||||
if (!File.Exists(saveFullName)) {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
File.Delete(saveFullName);
|
||||
}
|
||||
|
||||
public string GetFullPath(FileModel fileModel) {
|
||||
string extension = Path.GetExtension(fileModel.FileName);
|
||||
string saveFileName = string.Format("{0}{1}", fileModel.FileID, extension);
|
||||
string saveFullName = Path.Combine(this.saveDirectory, saveFileName);
|
||||
return saveFullName;
|
||||
}
|
||||
}
|
||||
|
@ -10,4 +10,5 @@ public class FileModel {
|
||||
public string MimeType { get; set; }
|
||||
public string HashValue { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public bool IsDeleted { get; set; } = false;
|
||||
}
|
||||
|
8
Models/Request/FileDeleteModel.cs
Normal file
8
Models/Request/FileDeleteModel.cs
Normal file
@ -0,0 +1,8 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace StorageServer.Models.Request;
|
||||
|
||||
public class FileDeleteModel {
|
||||
[Required]
|
||||
public long FileID { get; set; }
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>disable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
25
StorageServer.sln
Normal file
25
StorageServer.sln
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.002.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StorageServer", "StorageServer.csproj", "{4BDA80C2-0B1E-4B29-993A-65572587066E}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4BDA80C2-0B1E-4B29-993A-65572587066E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4BDA80C2-0B1E-4B29-993A-65572587066E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4BDA80C2-0B1E-4B29-993A-65572587066E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4BDA80C2-0B1E-4B29-993A-65572587066E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F6E3DEC7-59C2-46F8-949E-F523A72DE0AE}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
119
test-client/index.html
Normal file
119
test-client/index.html
Normal file
@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>StorageServer</title>
|
||||
<link rel="stylesheet" href="https://devras.net/cloud/css/bootstrap.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="m-2">
|
||||
<form method="post" enctype="multipart/form-data" action="http://localhost:5000/File/Create" id="upload_form">
|
||||
<div class="form-group row">
|
||||
<div class="col-3">
|
||||
<label for="file" class="form-label">アップロードするファイル</label>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<input type="file" name="File" accept="*/*" id="file" class="form-control" multiple />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">アップロード</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<img src="" class="img-fluid" id="img" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ul class="list-group" id="file_list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const uploadForm = document.getElementById('upload_form');
|
||||
const fileInput = document.getElementById('file');
|
||||
const imageContainer = document.getElementById('img');
|
||||
const fileList = document.getElementById('file_list');
|
||||
|
||||
const appendFile = (fileId, fileName) => {
|
||||
const a = document.createElement('a');
|
||||
a.href = `http://localhost:5000/File/Read/${fileId}`;
|
||||
a.textContent = `${fileName}`;
|
||||
const li = document.createElement('li');
|
||||
li.classList.add('list-group-item');
|
||||
li.append(a);
|
||||
|
||||
fileList.append(li);
|
||||
return li;
|
||||
};
|
||||
|
||||
const readFileList = async () => {
|
||||
fileList.innerHTML = ``;
|
||||
|
||||
const response = await fetch('http://localhost:5000/FileList');
|
||||
const json = await response.json();
|
||||
for (const item of json)
|
||||
{
|
||||
const li = appendFile(item.fileID, item.fileName);
|
||||
const a = li.querySelector('a');
|
||||
if (item.mimeType.startsWith("image/"))
|
||||
{
|
||||
a.addEventListener('click', async e => {
|
||||
e.preventDefault();
|
||||
imageContainer.src = a.href;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const uploadRequest = async (file, fileName) => {
|
||||
const fd = new FormData();
|
||||
fd.append("File", file);
|
||||
if (typeof fileName === "string" && fileName.length > 0) {
|
||||
fd.append("FileName", fileName);
|
||||
}
|
||||
|
||||
const response = await fetch("http://localhost:5000/File/Create", {
|
||||
method: "POST",
|
||||
body: fd,
|
||||
}).catch(() => {
|
||||
return {
|
||||
ok: false,
|
||||
};
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
};
|
||||
|
||||
uploadForm.addEventListener('submit', async e => {
|
||||
e.preventDefault();
|
||||
|
||||
if (fileInput.files.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const promises = [];
|
||||
for (let i = 0 ; i < fileInput.files.length ; i++) {
|
||||
promises.push(uploadRequest(fileInput.files[i]));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
fileInput.value = ``;
|
||||
await readFileList();
|
||||
});
|
||||
|
||||
readFileList();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user