I used Visual Studio 2017 and .NETCore 1.1. To do this, I follow the following rules: 1. Enter the code in MongoDB GridFS, create an interface, for example
public interface IGridFsRepository : IDisposable { Task<string> UploadAsync(IFormFile file); Task<bool> AnyAsync(ObjectId id); Task<bool> AnyAsync(string fileName); Task DeleteAsync(string fileName); Task DeleteAsync(ObjectId id); Task<GridFSDownloadStream<ObjectId>> DownloadAsync(string fileName); Task<GridFSDownloadStream<ObjectId>> DownloadAsync(ObjectId id); object GetAllFilesByContentType(string contentType, int skip, int take); object GetAllFiles(int skip, int take); }
then create MongoDbCdnContext:
public abstract class MongoDbCdnContext { public IGridFSBucket GridFsBucket {get;} protected MongoDbCdnContext(string connectionStringName) { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); var connectionString = config.GetConnectionString(connectionStringName); var connection = new MongoUrl(connectionString); var settings = MongoClientSettings.FromUrl(connection);
then execute it:
public class GridFsRepository : MongoDbCdnContext, IGridFsRepository { public GridFsRepository() : base("MongoCdn") { } public async Task<string> UploadAsync(IFormFile file) { var options = new GridFSUploadOptions { Metadata = new BsonDocument("contentType", file.ContentType) }; using (var reader = new StreamReader((Stream)file.OpenReadStream())) { var stream = reader.BaseStream; var fileId = await GridFsBucket.UploadFromStreamAsync(file.FileName, stream, options); return fileId.ToString(); } } public async Task<bool> AnyAsync(ObjectId id) { var filter = Builders<GridFSFileInfo>.Filter.Eq("_id", id); return await GridFsBucket.Find(filter).AnyAsync(); } public Task<bool> AnyAsync(string fileName) { var filter = Builders<GridFSFileInfo>.Filter.Where(x => x.Filename == fileName); return GridFsBucket.Find(filter).AnyAsync(); } public async Task DeleteAsync(string fileName) { var fileInfo = await GetFileInfoAsync(fileName); if (fileInfo != null) await DeleteAsync(fileInfo.Id); } public async Task DeleteAsync(ObjectId id) { await GridFsBucket.DeleteAsync(id); } private async Task<GridFSFileInfo> GetFileInfoAsync(string fileName) { var filter = Builders<GridFSFileInfo>.Filter.Eq(x => x.Filename, fileName); var fileInfo = await GridFsBucket.Find(filter).FirstOrDefaultAsync(); return fileInfo; } public async Task<GridFSDownloadStream<ObjectId>> DownloadAsync(ObjectId id) { return await GridFsBucket.OpenDownloadStreamAsync(id); } public async Task<GridFSDownloadStream<ObjectId>> DownloadAsync(string fileName) { return await GridFsBucket.OpenDownloadStreamByNameAsync(fileName); } public IEnumerable<GridFSFileInfoDto> GetAllFilesByContentType(string contentType, int skip, int take) { var filter = Builders<GridFSFileInfo>.Filter .Eq(info => info.Metadata, new BsonDocument(new BsonElement("contentType", contentType))); var options = new GridFSFindOptions { Limit = take, Skip = skip, }; var stream = GridFsBucket.Find(filter, options) .ToList() .Select(s => new GridFSFileInfoDto { Id = s.Id, Filename = s.Filename, MetaData = s.Metadata, Length = s.Length + "", UploadDateTime = s.UploadDateTime, }) .ToList(); return stream; } public IEnumerable<GridFSFileInfoDto> GetAllFiles(int skip, int take) { var options = new GridFSFindOptions { Limit = take, Skip = skip, }; var stream = GridFsBucket.Find(new BsonDocumentFilterDefinition<GridFSFileInfo<ObjectId>>(new BsonDocument()), options) .ToList() .Select(s => new GridFSFileInfoDto { Id = s.Id, Filename = s.Filename, MetaData = s.Metadata, Length = s.Length + "", UploadDateTime = s.UploadDateTime, }) .ToList(); return stream; } public void Dispose() { GC.SuppressFinalize(this); } }
then create a controller in .netcore web api
[EnableCors("AllowAll")] [ValidateModel] [Route("api/files")] public class FileController : Controller { private readonly IGridFsRepository _gridFsManager; public FileController(IGridFsRepository gridFsRepository) { _gridFsManager = gridFsRepository; } [AllowAnonymous] [HttpGet("{fileName}",Name = "GetByFileName")] public async Task<IActionResult> GetByFileName(string fileName) { return Ok(await _gridFsManager.DownloadAsync(fileName)); } [AllowAnonymous] [HttpGet("{id}",Name = "GetById")] public async Task<IActionResult> GetByFileName(ObjectId id) { return Ok(await _gridFsManager.DownloadAsync(id)); } [HttpPost] public async Task<IActionResult> Upload([FromForm] IFormFile file) { if (file != null) { if (file.ContentType.Contains("image")) return BadRequest("Sorry only image jpg/jpeg/png accepted"); if (file.Length >= (300 * 1024)) return BadRequest($"Sorry {file.FileName} is exceeds 300kb"); await _gridFsManager.DeleteAsync(file.FileName); await _gridFsManager.UploadAsync(file); } return NoContent(); } [HttpDelete] public async Task<IActionResult> Delete(string id) { await _gridFsManager.DeleteAsync(id); return NoContent(); } }
please remember to solve the problem:
services.AddScoped<IGridFsRepository, GridFsRepository>();
to file from html:
<div class="btn"> <span>Logo</span> <input type="file" data-ng-model="cp.data.file" id="selectedFile" name="selectedFile"> </div>
allows you to go to the user interface level: first create an angular factory:
(function () { "use strict"; angular.module("appCdn", []) .factory('fileUploader', ["$http", function ($http) { return { upload: function (url, file, fileMaxSize, fileName, callback) { if (this.isValidFileSize(fileMaxSize, file)) { var fd = new FormData(); //Create FormData object if (fileName) fd.append("file", file, fileName); else fd.append("file", file); $http.post(url, fd, { transformRequest: angular.identity, headers: { 'Content-Type': undefined } }).success(function (data) { callback(); }).error(function (data) { Materialize.toast("Sorry! error in file upload", 4000, 'red'); }); } else { Materialize.toast("Sorry! " + file.name + " exceeds 300kb", 4000, 'red'); } }, isValidFileSize: function (maximumAllowedSize, file) { if (file.size >= maximumAllowedSize) { return false; } else { return true; } } }; } ]); })();
after that create an angular controller:
angular.module('ecom').controller('companyProfileCtrl', ['$http', 'config', "confirmation", "fileUploader",companyProfile]); function companyProfile($http, config, confirmation, fileUploader) { var vm = this; vm.getProfile = function () { $http.get(config.apiUrl + "companyProfile") .success(function (response) { vm.data = response; }); }; vm.save = function (profile) { confirmation.confirm(function () { $http.post(config.apiUrl + "companyProfile", profile) .success(function (data) { var fileName = ""; if (profile.id) { fileName = profile.id; } else { fileName = data; } vm.upload(fileName, function () { Materialize.toast("succeeded", 4000, 'green'); window.location.href = window.history.back(); }); }) .error(function (data) { Materialize.toast(data, 4000, 'red'); }); }); }; vm.upload = function (fileName, callback) { var photo = document.getElementById("selectedFile"); var file = photo.files[0]; if (file) {fileUploader.upload(config.cdnUrl + "files",
finally to show the image in html:
<div><img src="http://localhost:41792/api/files/{{cp.data.id}}" class="img-responsive visible-md visible-lg img-margin-desktop" width="350" height="167" /> </div>
finally we did it. it's all. I am always looking forward to criticism.