using System.Net.Http;
using System.Net;
using System.Web.Http;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System;
/////http://127.0.0.1:9981/api/file/browse
///
///
///
namespace WebApi
{
///
///
///
[RoutePrefix("api/file")]
public class IFileController : ApiController
{
// 基础路径配置
private readonly string _basePath = @"D:\CameraImg";
///
/// 请求DTO
///
public class FileRequestDto
{
public string RelativePath { get; set; } = "";
}
///
/// 浏览文件或文件夹,前端传相对路径,返回文件夹内容或文件流(图片等可预览)
///
[HttpPost]
[Route("browse")]
public IHttpActionResult BrowsePath([FromBody] FileRequestDto request)
{
try
{
if (request == null)
request = new FileRequestDto();
if (string.IsNullOrEmpty(request.RelativePath) || request.RelativePath == "/")
{
request.RelativePath = "";
}
string fullPath = Path.Combine(_basePath, request.RelativePath.Replace('/', Path.DirectorySeparatorChar));
if (!IsPathSafe(fullPath))
{
return Ok(new { success = false, message = "无效的路径" });
}
if (!Directory.Exists(fullPath) && !System.IO.File.Exists(fullPath))
{
return Ok(new { success = false, message = "路径不存在" });
}
if (System.IO.File.Exists(fullPath))
{
return GetFilePreview(fullPath, request.RelativePath);
}
if (Directory.Exists(fullPath))
{
return GetDirectoryContents(fullPath, request.RelativePath);
}
return Ok(new { success = false, message = "路径不存在" });
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"服务器错误: {ex.Message}" });
}
}
///
/// 获取文件预览数据(图片/文本base64,前端可直接预览)
///
private IHttpActionResult GetFilePreview(string fullPath, string relativePath)
{
try
{
var fileInfo = new FileInfo(fullPath);
var extension = fileInfo.Extension.ToLowerInvariant();
var previewable = IsPreviewableFile(extension);
var contentType = GetContentType(fileInfo.Name);
bool tooLarge = fileInfo.Length > 10 * 1024 * 1024; // 10MB限制
string base64String = null;
string dataUrl = null;
bool canPreview = previewable && !tooLarge;
if (canPreview)
{
var fileBytes = System.IO.File.ReadAllBytes(fullPath);
base64String = Convert.ToBase64String(fileBytes);
dataUrl = $"data:{contentType};base64,{base64String}";
}
var result = new
{
success = true,
type = "file",
path = relativePath,
name = fileInfo.Name,
size = fileInfo.Length,
extension = fileInfo.Extension,
contentType = contentType,
isPreviewable = canPreview,
base64Data = base64String,
dataUrl = dataUrl,
created = fileInfo.CreationTime,
modified = fileInfo.LastWriteTime,
message = tooLarge ? "文件过大,无法预览,可下载" : null
};
return Ok(result);
}
catch (Exception ex)
{
return Ok(new { success = false, message = $"获取文件预览失败: {ex.Message}" });
}
}
///
/// 判断文件是否可预览
///
private bool IsPreviewableFile(string extension)
{
var previewableExtensions = new[]
{
".bmp", ".jpg", ".jpeg", ".png", ".gif", ".tiff", ".tif", ".webp",
".txt", ".json", ".xml", ".csv", ".log", ".md"
};
return previewableExtensions.Contains(extension);
}
///
/// 安全检查:确保路径在基础目录内,防止路径遍历攻击
///
private bool IsPathSafe(string fullPath)
{
try
{
var basePath = Path.GetFullPath(_basePath);
var requestedPath = Path.GetFullPath(fullPath);
return requestedPath.StartsWith(basePath, StringComparison.OrdinalIgnoreCase);
}
catch
{
return false;
}
}
///
/// 根据文件扩展名获取MIME类型(兼容C# 7.3)
///
private string GetContentType(string fileName)
{
var extension = Path.GetExtension(fileName).ToLowerInvariant();
if (extension == ".bmp") return "image/bmp";
if (extension == ".jpg" || extension == ".jpeg") return "image/jpeg";
if (extension == ".png") return "image/png";
if (extension == ".gif") return "image/gif";
if (extension == ".tiff" || extension == ".tif") return "image/tiff";
if (extension == ".webp") return "image/webp";
if (extension == ".pdf") return "application/pdf";
if (extension == ".txt") return "text/plain";
if (extension == ".json") return "application/json";
if (extension == ".xml") return "application/xml";
if (extension == ".csv") return "text/csv";
if (extension == ".md") return "text/markdown";
if (extension == ".log") return "text/plain";
if (extension == ".zip") return "application/zip";
if (extension == ".rar") return "application/x-rar-compressed";
return "application/octet-stream";
}
private IHttpActionResult GetDirectoryContents(string fullPath, string relativePath)
{
try
{
var items = new List