188 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			C#
		
	
	
using IRaCIS.Core.Application.Helper;
 | 
						||
using IRaCIS.Core.Domain.Share;
 | 
						||
using IRaCIS.Core.Infrastructure.Extention;
 | 
						||
using Microsoft.AspNetCore.Hosting;
 | 
						||
using Microsoft.AspNetCore.Http;
 | 
						||
using Microsoft.Extensions.FileProviders;
 | 
						||
using Microsoft.Extensions.FileProviders.Physical;
 | 
						||
using Microsoft.Extensions.Logging;
 | 
						||
using Newtonsoft.Json;
 | 
						||
using System.IO;
 | 
						||
using System.Linq;
 | 
						||
using System.Threading.Tasks;
 | 
						||
 | 
						||
namespace IRaCIS.Core.API
 | 
						||
{
 | 
						||
 | 
						||
 | 
						||
    public class MultiDiskStaticFilesMiddleware
 | 
						||
    {
 | 
						||
        private readonly RequestDelegate _next;
 | 
						||
        private readonly IWebHostEnvironment _hostingEnv;
 | 
						||
        private readonly ILoggerFactory _loggerFactory;
 | 
						||
 | 
						||
        private string iRaCISDefaultDataFolder = string.Empty;
 | 
						||
 | 
						||
        public MultiDiskStaticFilesMiddleware(RequestDelegate next, IWebHostEnvironment hostingEnv, ILoggerFactory loggerFactory)
 | 
						||
        {
 | 
						||
            _next = next;
 | 
						||
            _hostingEnv = hostingEnv;
 | 
						||
            _loggerFactory = loggerFactory;
 | 
						||
 | 
						||
            iRaCISDefaultDataFolder = FileStoreHelper.GetIRaCISRootDataFolder(_hostingEnv);
 | 
						||
 | 
						||
            if (!Directory.Exists(iRaCISDefaultDataFolder))
 | 
						||
            {
 | 
						||
                Directory.CreateDirectory(iRaCISDefaultDataFolder);
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        public async Task Invoke(HttpContext context)
 | 
						||
        {
 | 
						||
            var path = context.Request.Path.Value;
 | 
						||
            var isIRacisFile = path.StartsWith($"/{StaticData.Folder.IRaCISDataFolder}");
 | 
						||
 | 
						||
            var isDicomFile = isIRacisFile && path.Contains($"{StaticData.Folder.DicomFolder}");
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            //先从默认里面去找
 | 
						||
            if (isIRacisFile)
 | 
						||
            {
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                #region 方式二
 | 
						||
 | 
						||
                //var defaultFileProvider = new PhysicalFileProvider(iRaCISDefaultDataFolder);
 | 
						||
 | 
						||
                //var staticFileOptions = new StaticFileOptions
 | 
						||
                //{
 | 
						||
                //    FileProvider = defaultFileProvider,
 | 
						||
                //    RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
 | 
						||
                //    ServeUnknownFileTypes = true,
 | 
						||
                //    DefaultContentType = "application/octet-stream"
 | 
						||
                //};
 | 
						||
 | 
						||
                //var a = defaultFileProvider.GetFileInfo(context.Request.Path).Exists;
 | 
						||
 | 
						||
                //var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(staticFileOptions), _loggerFactory);
 | 
						||
                //await staticFileMiddleware.Invoke(context);
 | 
						||
 | 
						||
                #endregion
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                #region 文档上传默认会加wwwroot 奇怪...
 | 
						||
 | 
						||
                var defaultFileProvider = new PhysicalFileProvider(FileStoreHelper.GetIRaCISRootPath(_hostingEnv));
 | 
						||
 | 
						||
                if (defaultFileProvider.GetFileInfo(path).Exists)
 | 
						||
                {
 | 
						||
 | 
						||
                    var actrualPath = defaultFileProvider.GetFileInfo(path).PhysicalPath;
 | 
						||
 | 
						||
                    await context.Response.SendFileAsync(new PhysicalFileInfo(new FileInfo(actrualPath)));
 | 
						||
 | 
						||
                    return;
 | 
						||
                }
 | 
						||
                #endregion
 | 
						||
 | 
						||
            }
 | 
						||
 | 
						||
            //没找到  
 | 
						||
            //dicom影像,从多个文件夹尝试,因为会存在切换磁盘
 | 
						||
            if (isDicomFile)
 | 
						||
            {
 | 
						||
                var defaultRoot = Path.GetPathRoot(iRaCISDefaultDataFolder);
 | 
						||
 | 
						||
                //除默认部署路径的其他路径
 | 
						||
                var disks = DriveInfo.GetDrives()
 | 
						||
                .Where(d => d.IsReady && d.DriveType == DriveType.Fixed)/*.Where(t => !t.Name.Contains("C") && !t.Name.Contains("c"))*/
 | 
						||
                .OrderBy(d => d.AvailableFreeSpace)
 | 
						||
                .Select(d => d.RootDirectory.FullName)
 | 
						||
                .ToArray().Where(t => !t.Contains(defaultRoot));
 | 
						||
 | 
						||
 | 
						||
                foreach (var item in disks)
 | 
						||
                {
 | 
						||
                    var otherFileStoreFolder = Path.Combine(item, _hostingEnv.EnvironmentName);
 | 
						||
 | 
						||
                    if (!Directory.Exists(otherFileStoreFolder))
 | 
						||
                    {
 | 
						||
                        continue;
 | 
						||
                    }
 | 
						||
 | 
						||
                    var otherFileProvider = new PhysicalFileProvider(otherFileStoreFolder);
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                    if (otherFileProvider.GetFileInfo(path).Exists)
 | 
						||
                    {
 | 
						||
 | 
						||
                        var actrualPath = otherFileProvider.GetFileInfo(path).PhysicalPath;
 | 
						||
 | 
						||
                        //方式一
 | 
						||
                        await context.Response.SendFileAsync(new PhysicalFileInfo(new FileInfo(actrualPath)));
 | 
						||
 | 
						||
                        #region 方式二  报错  otherFileProvider 应该还包含/{StaticData.Folder.IRaCISDataFolder} 这一层级
 | 
						||
                        //var otherStaticFileOptions = new StaticFileOptions
 | 
						||
                        //{
 | 
						||
                        //    FileProvider = otherFileProvider,
 | 
						||
                        //    RequestPath = $"/{StaticData.Folder.IRaCISDataFolder}",
 | 
						||
                        //    ServeUnknownFileTypes = true,
 | 
						||
                        //    DefaultContentType = "application/octet-stream"
 | 
						||
                        //};
 | 
						||
                        //var staticFileMiddleware = new StaticFileMiddleware(_next, _hostingEnv, Options.Create(otherStaticFileOptions), _loggerFactory);
 | 
						||
                        //await staticFileMiddleware.Invoke(context);
 | 
						||
                        #endregion
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                        return;
 | 
						||
                    }
 | 
						||
                }
 | 
						||
 | 
						||
                // 如果没有找到文件,返回404
 | 
						||
                context.Response.StatusCode = 404;
 | 
						||
                context.Response.ContentType = "application/json";
 | 
						||
 | 
						||
                await context.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk("File not found")));
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
            // 如果所有磁盘都不存在所请求的文件,则将请求传递给下一个中间件组件。
 | 
						||
            await _next.Invoke(context);
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        //private static string GetContentType(string path)
 | 
						||
        //{
 | 
						||
        //    var provider = new FileExtensionContentTypeProvider();
 | 
						||
        //    if (!provider.TryGetContentType(path, out var contentType))
 | 
						||
        //    {
 | 
						||
        //        contentType = "application/octet-stream";
 | 
						||
        //    }
 | 
						||
 | 
						||
        //    return contentType;
 | 
						||
        //}
 | 
						||
 | 
						||
        //private async Task ServeFileAsync(HttpContext context, IFileInfo fileInfo)
 | 
						||
        //{
 | 
						||
        //    var response = context.Response;
 | 
						||
        //    response.ContentType = GetContentType(fileInfo.PhysicalPath);
 | 
						||
 | 
						||
        //    using (var fileStream = fileInfo.CreateReadStream())
 | 
						||
        //    {
 | 
						||
        //        await fileStream.CopyToAsync(response.Body);
 | 
						||
        //    }
 | 
						||
        //}
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
}
 |