Browse Source

Fixed #864: Blog module file upload problem.

pull/880/head
Halil ibrahim Kalkan 7 years ago
parent
commit
cda9870cd0
  1. 15
      framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Http/AbpFormFileExtensions.cs
  2. 1
      modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs
  3. 4
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/FileUploadOutputDto.cs
  4. 4
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/IFileAppService.cs
  5. 7
      modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/RawFileDto.cs
  6. 2
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/BlogFileOptions.cs
  7. 22
      modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/FileAppService.cs
  8. 60
      modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs
  9. 0
      modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/FileUploadResult.cs
  10. 55
      modules/blogging/src/Volo.Blogging.Web/Areas/Blog/Controllers/FilesController.cs
  11. 23
      modules/blogging/src/Volo.Blogging.Web/Hosting/FormFileExtensions.cs
  12. 4
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/edit.js
  13. 4
      modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/new.js
  14. 1
      samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingServiceHostModule.cs
  15. BIN
      samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/100d4c0445cbf55f687339ec8e656abb.jpg
  16. 0
      samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/90974f3f1edb4ab0a10cf9759fd5f9ae.png
  17. 0
      samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/ec882345a403be325bc539ebda211e79.jpg

15
framework/src/Volo.Abp.AspNetCore.Mvc/Microsoft/AspNetCore/Http/AbpFormFileExtensions.cs

@ -0,0 +1,15 @@
using System.IO;
namespace Microsoft.AspNetCore.Http
{
public static class AbpFormFileExtensions
{
public static byte[] GetAllBytes(this IFormFile file)
{
using (var stream = file.OpenReadStream())
{
return stream.GetAllBytes();
}
}
}
}

1
modules/blogging/app/Volo.BloggingTestApp/BloggingTestAppModule.cs

@ -114,7 +114,6 @@ namespace Volo.BloggingTestApp
Configure<BlogFileOptions>(options =>
{
options.FileUploadLocalFolder = Path.Combine(hostingEnvironment.WebRootPath, "files");
options.FileUploadUrlRoot = "/files/";
});
}

4
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/FileUploadOutputDto.cs

@ -2,6 +2,8 @@
{
public class FileUploadOutputDto
{
public string Url { get; set; }
public string Name { get; set; }
public string WebUrl { get; set; }
}
}

4
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/IFileAppService.cs

@ -5,6 +5,8 @@ namespace Volo.Blogging.Files
{
public interface IFileAppService : IApplicationService
{
Task<FileUploadOutputDto> UploadAsync(FileUploadInputDto input);
Task<RawFileDto> GetAsync(string name);
Task<FileUploadOutputDto> CreateAsync(FileUploadInputDto input);
}
}

7
modules/blogging/src/Volo.Blogging.Application.Contracts/Volo/Blogging/Files/RawFileDto.cs

@ -0,0 +1,7 @@
namespace Volo.Blogging.Files
{
public class RawFileDto
{
public byte[] Bytes { get; set; }
}
}

2
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/BlogFileOptions.cs

@ -7,7 +7,5 @@
public class BlogFileOptions
{
public string FileUploadLocalFolder { get; set; }
public string FileUploadUrlRoot { get; set; }
}
}

22
modules/blogging/src/Volo.Blogging.Application/Volo/Blogging/Files/FileAppService.cs

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Threading.Tasks;
@ -20,7 +19,21 @@ namespace Volo.Blogging.Files
Options = options.Value;
}
public virtual Task<FileUploadOutputDto> UploadAsync(FileUploadInputDto input)
public virtual Task<RawFileDto> GetAsync(string name)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
var filePath = Path.Combine(Options.FileUploadLocalFolder, name);
return Task.FromResult(
new RawFileDto
{
Bytes = File.ReadAllBytes(filePath)
}
);
}
public virtual Task<FileUploadOutputDto> CreateAsync(FileUploadInputDto input)
{
if (input.Bytes.IsNullOrEmpty())
{
@ -44,7 +57,8 @@ namespace Volo.Blogging.Files
return Task.FromResult(new FileUploadOutputDto
{
Url = Options.FileUploadUrlRoot.EnsureEndsWith('/') + uniqueFileName
Name = uniqueFileName,
WebUrl = "/api/blogging/files/www/" + uniqueFileName
});
}

60
modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogFilesController.cs

@ -1,7 +1,11 @@
using System.Threading.Tasks;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Http;
using Volo.Blogging.Areas.Blog.Models;
using Volo.Blogging.Files;
namespace Volo.Blogging
@ -18,10 +22,60 @@ namespace Volo.Blogging
_fileAppService = fileAppService;
}
[HttpGet]
[Route("{name}")]
public Task<RawFileDto> GetAsync(string name) //TODO: output cache would be good
{
return _fileAppService.GetAsync(name);
}
[HttpGet]
[Route("www/{name}")]
public async Task<FileResult> GetForWebAsync(string name) //TODO: output cache would be good
{
var file = await _fileAppService.GetAsync(name);
return File(
file.Bytes,
MimeTypes.GetByExtension(Path.GetExtension(name))
);
}
[HttpPost]
public Task<FileUploadOutputDto> UploadAsync(FileUploadInputDto input)
public Task<FileUploadOutputDto> CreateAsync(FileUploadInputDto input)
{
return _fileAppService.UploadAsync(input);
return _fileAppService.CreateAsync(input);
}
[HttpPost]
[Route("images/upload")]
public async Task<JsonResult> UploadImage(IFormFile file)
{
//TODO: localize exception messages
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!");
}
var output = await _fileAppService.CreateAsync(
new FileUploadInputDto
{
Bytes = file.GetAllBytes(),
Name = file.FileName
}
);
return Json(new FileUploadResult(output.WebUrl));
}
}
}

0
modules/blogging/src/Volo.Blogging.Web/Areas/Blog/Models/FileUploadResult.cs → modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/FileUploadResult.cs

55
modules/blogging/src/Volo.Blogging.Web/Areas/Blog/Controllers/FilesController.cs

@ -1,55 +0,0 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Blogging.Areas.Blog.Models;
using Volo.Blogging.Files;
using Volo.Blogging.Hosting;
namespace Volo.Blogging.Areas.Blog.Controllers
{
//TODO: This may be moved to HttpApi project since it may be needed by a SPA too.
[Area("Blog")]
[Route("Blog/[controller]/[action]")]
public class FilesController : AbpController
{
private readonly IFileAppService _fileAppService;
public FilesController(IFileAppService fileAppService)
{
_fileAppService = fileAppService;
}
[HttpPost]
public async Task<JsonResult> UploadImage(IFormFile file)
{
//TODO: localize exception messages
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!");
}
var output = await _fileAppService.UploadAsync(
new FileUploadInputDto
{
Bytes = file.AsBytes(),
Name = file.FileName
}
);
return Json(new FileUploadResult(output.Url));
}
}
}

23
modules/blogging/src/Volo.Blogging.Web/Hosting/FormFileExtensions.cs

@ -1,23 +0,0 @@
using System.IO;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
using Volo.Abp;
namespace Volo.Blogging.Hosting
{
public static class FormFileExtensions
{
public static byte[] AsBytes(this IFormFile file) //TODO: Move to the framework (rename to GetBytes)
{
using (var stream = file.OpenReadStream())
{
return stream.GetAllBytes();
}
}
public static void ValidateImage([CanBeNull] this IFormFile file)
{
}
}
}

4
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/edit.js

@ -17,7 +17,7 @@
$.ajax({
type: "POST",
url: "/Blog/Files/UploadImage",
url: "/api/blogging/files/images/upload",
data: formData,
contentType: false,
processData: false,
@ -42,7 +42,7 @@
$.ajax({
type: "POST",
url: "/Blog/Files/UploadImage",
url: "/api/blogging/files/images/upload",
data: formData,
contentType: false,
processData: false,

4
modules/blogging/src/Volo.Blogging.Web/Pages/Blog/Posts/new.js

@ -19,7 +19,7 @@
$.ajax({
type: "POST",
url: "/Blog/Files/UploadImage",
url: "/api/blogging/files/images/upload",
data: formData,
contentType: false,
processData: false,
@ -43,7 +43,7 @@
$.ajax({
type: "POST",
url: "/Blog/Files/UploadImage",
url: "/api/blogging/files/images/upload",
data: formData,
contentType: false,
processData: false,

1
samples/MicroserviceDemo/microservices/BloggingService.Host/BloggingServiceHostModule.cs

@ -85,7 +85,6 @@ namespace BloggingService.Host
Configure<BlogFileOptions>(options =>
{
options.FileUploadLocalFolder = Path.Combine(hostingEnvironment.WebRootPath, "files");
options.FileUploadUrlRoot = "/files/";
});
context.Services.AddDistributedRedisCache(options =>

BIN
samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/100d4c0445cbf55f687339ec8e656abb.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

0
samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/files/90974f3f1edb4ab0a10cf9759fd5f9ae.png → samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/90974f3f1edb4ab0a10cf9759fd5f9ae.png

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 154 KiB

0
samples/MicroserviceDemo/applications/PublicWebSite.Host/wwwroot/files/ec882345a403be325bc539ebda211e79.jpg → samples/MicroserviceDemo/microservices/BloggingService.Host/wwwroot/files/ec882345a403be325bc539ebda211e79.jpg

Before

Width:  |  Height:  |  Size: 400 KiB

After

Width:  |  Height:  |  Size: 400 KiB

Loading…
Cancel
Save