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]
|
[HttpGet]
|
||||||
public IActionResult Read(FileReadModel model) {
|
public IActionResult Read(FileReadModel model) {
|
||||||
if (!ModelState.IsValid) {
|
if (!ModelState.IsValid) {
|
||||||
@ -84,4 +102,26 @@ public class FileController : Controller
|
|||||||
return Problem();
|
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) {
|
public async Task SaveFile(FileModel fileModel, FileStream fs) {
|
||||||
string extension = Path.GetExtension(fileModel.FileName);
|
string saveFullName = GetFullPath(fileModel);
|
||||||
string saveFileName = string.Format("{0}{1}", fileModel.FileID, extension);
|
|
||||||
string saveFullName = Path.Combine(this.saveDirectory, saveFileName);
|
|
||||||
using (FileStream dest = new FileStream(saveFullName, FileMode.OpenOrCreate)) {
|
using (FileStream dest = new FileStream(saveFullName, FileMode.OpenOrCreate)) {
|
||||||
await fs.CopyToAsync(dest);
|
await fs.CopyToAsync(dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stream GetFile(FileModel fileModel) {
|
public Stream GetFile(FileModel fileModel) {
|
||||||
string extension = Path.GetExtension(fileModel.FileName);
|
string saveFullName = GetFullPath(fileModel);
|
||||||
string saveFileName = string.Format("{0}{1}", fileModel.FileID, extension);
|
|
||||||
string saveFullName = Path.Combine(this.saveDirectory, saveFileName);
|
|
||||||
if (!File.Exists(saveFullName)) {
|
if (!File.Exists(saveFullName)) {
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new FileStream(saveFullName, FileMode.Open);
|
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 MimeType { get; set; }
|
||||||
public string HashValue { get; set; }
|
public string HashValue { get; set; }
|
||||||
public DateTime CreatedAt { 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">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Nullable>disable</Nullable>
|
<Nullable>disable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</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