如何使用 MongoDB GridFS 和 AngularJs 在 dotnet 核心中创建 CDN 服务器 [英] How to create a CDN server in dotnet core using MongoDB GridFS and AngularJs

查看:26
本文介绍了如何使用 MongoDB GridFS 和 AngularJs 在 dotnet 核心中创建 CDN 服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们想使用 MongoDB GridFS 和 angular js 在 .net core 中创建一个名为 CDN 的解耦文件服务器.

从各种来源我尽力解决这个问题.最后我们做到了.

解决方案

我使用了 Visual Studio 2017 和 .NETCore 1.1为此,我遵循以下几点:1. 在 MongoDB GridFS 中编写代码创建一个像

这样的界面

公共接口 IGridFsRepository : IDisposable{任务<字符串>UploadAsync(IFormFile 文件);任务AnyAsync(ObjectId id);任务AnyAsync(字符串文件名);任务 DeleteAsync(string fileName);任务 DeleteAsync(ObjectId id);任务<GridFSDownloadStream<ObjectId>>下载异步(字符串文件名);任务<GridFSDownloadStream<ObjectId>>DownloadAsync(ObjectId id);object GetAllFilesByContentType(string contentType, int skip, int拿);object GetAllFiles(int skip, int take);}

然后创建 MongoDbCdnContext:

 公共抽象类 MongoDbCdnContext{公共 IGridFSBucket GridFsBucket {get;}受保护的 MongoDbCdnContext(string connectionStringName){var config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").建造();变量连接字符串 =config.GetConnectionString(connectionStringName);var connection = new MongoUrl(connectionString);var settings = MongoClientSettings.FromUrl(connection);//#如果调试//settings.ClusterConfigurator = builder =>builder.Subscribe(started =>//{//Debug.Write(started.Command);//});//#万一var client = new MongoClient(settings);var database = client.GetDatabase(connection.DatabaseName);GridFsBucket = 新的 GridFSBucket(数据库);}}

然后实现它:

 公共类 GridFsRepository : MongoDbCdnContext,IGridFsRepository{公共 GridFsRepository() : base("MongoCdn"){}公共异步任务上传异步(IFormFile 文件){var 选项 = 新的 GridFSUploadOptions{元数据 = new BsonDocument("contentType", file.ContentType)};使用 (var reader = newStreamReader((Stream)file.OpenReadStream())){var stream = reader.BaseStream;var fileId = 等待GridFsBucket.UploadFromStreamAsync(file.FileName, stream,选项);返回 fileId.ToString();}}公共异步任务AnyAsync(ObjectId id){var filter = Builders.Filter.Eq("_id", id);返回等待 GridFsBucket.Find(filter).AnyAsync();}公共任务AnyAsync(字符串文件名){var filter = Builders.Filter.Where(x =>x.文件名 == 文件名);返回 GridFsBucket.Find(filter).AnyAsync();}公共异步任务 DeleteAsync(字符串文件名){var fileInfo = await GetFileInfoAsync(fileName);如果(文件信息!= null)等待 DeleteAsync(fileInfo.Id);}公共异步任务 DeleteAsync(ObjectId id){等待 GridFsBucket.DeleteAsync(id);}私有异步任务GetFileInfoAsync(字符串文件名){var filter = Builders.Filter.Eq(x => x.Filename,文档名称);var 文件信息 = 等待GridFsBucket.Find(filter).FirstOrDefaultAsync();返回文件信息;}公共异步任务>DownloadAsync(ObjectId id){返回等待 GridFsBucket.OpenDownloadStreamAsync(id);}公共异步任务>下载异步(字符串文件名){返回等待GridFsBucket.OpenDownloadStreamByNameAsync(fileName);}公共 IEnumerableGetAllFilesByContentType(字符串contentType, int skip, int take){var filter = Builders.Filter.Eq(info => info.Metadata, new BsonDocument(newBsonElement("contentType", contentType)));var 选项 = 新的 GridFSFindOptions{限制 = 采取,跳过 = 跳过,};var stream = GridFsBucket.Find(过滤器,选项).ToList().Select(s => new GridFSFileInfoDto{Id = s.Id,文件名 = s.文件名,元数据 = s.元数据,长度 = s.Length + "",UploadDateTime = s.UploadDateTime,}).ToList();返回流;}公共 IEnumerableGetAllFiles(int skip, int take){var 选项 = 新的 GridFSFindOptions{限制 = 采取,跳过 = 跳过,};var stream = GridFsBucket.Find(newBsonDocumentFilterDefinition>(新BsonDocument()), 选项).ToList().Select(s => new GridFSFileInfoDto{Id = s.Id,文件名 = s.文件名,元数据 = s.元数据,长度 = s.Length + "",UploadDateTime = s.UploadDateTime,}).ToList();返回流;}公共无效处置(){GC.SuppressFinalize(this);}}

然后在.netcore web api中创建一个控制器

 [EnableCors("AllowAll")][验证模型][路由(api/文件")]公共类 FileController :控制器{私有只读 IGridFsRepository _gridFsManager;公共文件控制器(IGridFsRepository gridFsRepository){_gridFsManager = gridFsRepository;}[允许匿名][HttpGet("{fileName}",Name = "GetByFileName")]公共异步任务GetByFileName(字符串文件名){返回 Ok(await _gridFsManager.DownloadAsync(fileName));}[允许匿名][HttpGet("{id}",Name = "GetById")]公共异步任务GetByFileName(ObjectId id){返回 Ok(await _gridFsManager.DownloadAsync(id));}[HttpPost]公共异步任务上传([FromForm] IFormFile 文件){如果(文件!= null){if (file.ContentType.Contains("image"))return BadRequest("抱歉,只有图片 jpg/jpeg/png公认");if (file.Length >= (300 * 1024))return BadRequest($"Sorry {file.FileName} 超出了300kb");等待 _gridFsManager.DeleteAsync(file.FileName);等待 _gridFsManager.UploadAsync(file);}返回 NoContent();}[HttpDelete]公共异步任务删除(字符串ID){等待 _gridFsManager.DeleteAsync(id);返回 NoContent();}}

请不要忘记解决依赖:

 services.AddScoped();

从 html 到文件:

 

<span>标志</span><input type="file" data-ng-model="cp.data.file"id="selectedFile" name="selectedFile">

让我们进入 UI 层:首先创建一个角度工厂:

(函数(){严格使用";angular.module("appCdn", []).factory('fileUploader', ["$http", function ($http) {返回 {上传:函数(url,文件,fileMaxSize,fileName,回调){如果(this.isValidFileSize(fileMaxSize,文件)){var fd = new FormData();//创建FormData对象如果(文件名)fd.append("文件", 文件, 文件名);别的fd.append("文件", 文件);$http.post(url, fd, {变换请求:angular.identity,标头:{'内容类型':未定义}}).成功(功能(数据){打回来();}).错误(函数(数据){Materialize.toast("Sorry! error in file upload", 4000, 'red');});} 别的 {Materialize.toast("Sorry!" + file.name + " 超过 300kb", 4000, 'red');}},isValidFileSize: 函数 (maximumAllowedSize, 文件) {if (file.size >= maximumAllowedSize) {返回假;} 别的 {返回真;}}};}]);})();

然后创建一个角度控制器:

angular.module('ecom').controller('companyProfileCtrl',['$http', 'config', "confirmation", "fileUploader",companyProfile]);函数 companyProfile($http,配置,确认,fileUploader){var vm = 这个;vm.getProfile = 函数 () {$http.get(config.apiUrl + "companyProfile").成功(功能(响应){vm.data = 响应;});};vm.save = 函数(配置文件){确认.确认(功能(){$http.post(config.apiUrl + "companyProfile", 个人资料).成功(功能(数据){var 文件名 = "";如果(profile.id){文件名 = profile.id;} 别的 {文件名 = 数据;}vm.upload(文件名,功能 () {Materialize.toast("succeeded", 4000, 'green');window.location.href = window.history.back();});}).错误(功能(数据){Materialize.toast(data, 4000, 'red');});});};vm.upload = 函数(文件名,回调){var photo = document.getElementById("selectedFile");var file = photo.files[0];if (file) {fileUploader.upload(config.cdnUrl + "files",//300kb文件,1024 * 300,文件名,回调);}};};

最后以html显示图像:

 

我们终于做到了.这就是全部.我总是期待着接受批评.

We want to create a decoupled file server named CDN in .net core using MongoDB GridFS and angular js.

From various sources I tried my best to solve the issue. And finally we done this.

解决方案

I used Visual Studio 2017 and .NETCore 1.1 To do so I follow the followings: 1. Write Code in MongoDB GridFS create an interface like

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);
        //#if DEBUG
        //            settings.ClusterConfigurator = builder => 
       builder.Subscribe<CommandStartedEvent>(started =>
        //            {
        //                Debug.Write(started.Command);
        //            });
        //#endif
        var client = new MongoClient(settings);
        var database = client.GetDatabase(connection.DatabaseName);
        GridFsBucket = new GridFSBucket(database);
    }
  }

then implement 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 do not forget to resolve dependency:

     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>

lets go to UI layer: 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", 

          //300kb
              file, 1024  * 300, fileName, callback);
             }
         };
            };

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 done this. this is all. I always looking forward to receiving criticism.

这篇关于如何使用 MongoDB GridFS 和 AngularJs 在 dotnet 核心中创建 CDN 服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆