在.NET Core Web Api中使用阿里云OSS

1.安装Aliyun.OSS.SDK.NetCore

2.在appsettings.json里配置OSS相关参数

cs 复制代码
{
  
  "AliyunOss": {
    "Endpoint": "Bucket地域", // 与Bucket地域一致
    "BucketName": "Bucket名称", // 你的Bucket名称
    "AccessKeyId": "AccessKey ID", // 你的AccessKey ID
    "AccessKeySecret": "AccessKey Secret" // 你的AccessKey Secret
  }
}

9.3.创建配置模型类

cs 复制代码
namespace web01.Configurations
{
    public class AliyunOssSettings
    {
        public string Endpoint { get; set; } = string.Empty;
        public string AccessKeyId { get; set; } = string.Empty;
        public string AccessKeySecret { get; set; } = string.Empty;
        public string BucketName { get; set; } = string.Empty;
    }
}

9.4.创建OSS工具类

cs 复制代码
using Aliyun.OSS;
using Aliyun.OSS.Common;
using Microsoft.Extensions.Logging;
using System;
using System.IO;

namespace YourProject.Utils
{
    public class AliOssUtil
    {
        private readonly string _endpoint;
        private readonly string _accessKeyId;
        private readonly string _accessKeySecret;
        private readonly string _bucketName;
        private readonly ILogger<AliOssUtil> _logger;

        public AliOssUtil(
            string endpoint,
            string accessKeyId,
            string accessKeySecret,
            string bucketName,
            ILogger<AliOssUtil> logger)
        {
            // 步骤1:先给字段赋值(避免null引用)
            _endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint));
            _accessKeyId = accessKeyId ?? throw new ArgumentNullException(nameof(accessKeyId));
            _accessKeySecret = accessKeySecret ?? throw new ArgumentNullException(nameof(accessKeySecret));
            _bucketName = bucketName ?? throw new ArgumentNullException(nameof(bucketName));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            // 步骤2:再记录日志
            _logger.LogInformation("AliOssUtil初始化:Endpoint={Endpoint}, Bucket={Bucket}", _endpoint, _bucketName);
        }

        /// <summary>
        /// 上传文件到阿里云OSS,返回访问URL
        /// </summary>
        public string UploadFile(IFormFile file)
        {
            _logger.LogInformation("开始上传文件,文件名:{FileName}, 大小:{FileSize}KB", file.FileName, file.Length / 1024f);
            if (file == null || file.Length == 0)
            {
                throw new ArgumentException("文件不能为空", nameof(file));
            }

            // 生成唯一文件名(避免重复)
            string uniqueFileName = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";
            // 定义OSS中的文件路径(如:"uploads/20251026/xxx.jpg")
            string objectName = $"uploads/{DateTime.Now:yyyyMMdd}/{uniqueFileName}";

            try
            {
                // 创建OSS客户端
                var ossClient = new OssClient(_endpoint, _accessKeyId, _accessKeySecret);

                // 读取文件流并上传
                using var stream = file.OpenReadStream();
                if (stream == null || stream.Length == 0)
                {
                    _logger.LogError("文件流为空");
                    throw new ArgumentException("文件流无效", nameof(file));
                }
                ossClient.PutObject(_bucketName, objectName, stream);

                // 生成可访问的URL
                string fileUrl = $"https://{_bucketName}.{_endpoint}/{objectName}";
                _logger.LogInformation("文件上传成功,URL:{FileUrl}", fileUrl);
                return fileUrl;
            }
            catch (OssException oe)
            {
                _logger.LogError(oe, "OSS服务端异常:Code={Code}, Message={Message}", oe.ErrorCode, oe.Message);
                throw new Exception($"OSS上传失败:{oe.ErrorCode} - {oe.Message}", oe);
            }
            catch (ClientException ce)
            {
                _logger.LogError(ce, "OSS客户端异常:Message={Message}", ce.Message);
                throw new Exception($"OSS客户端错误:{ce.Message}", ce);
            }
        }
    }
}

9.5.在Program.cs中注册服务

cs 复制代码
var builder = WebApplication.CreateBuilder(args);
// 读取OSS配置
builder.Services.Configure<AliyunOssSettings>(builder.Configuration.GetSection("AliyunOss"));

// 注册OSS客户端(单例模式)
builder.Services.AddSingleton(sp =>
{
    var settings = sp.GetRequiredService<IOptions<AliyunOssSettings>>().Value;
    return new OssClient(settings.Endpoint, settings.AccessKeyId, settings.AccessKeySecret);
});

builder.Services.AddControllers();

9.6.控制器实现

cs 复制代码
using Aliyun.OSS;
using Aliyun.OSS.Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using web01.Configurations;
using web01.services;
using web01.Utils;
using YourProject.Utils;

namespace web01.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class FileUploadController : ControllerBase
    {
        private readonly OssClient _ossClient;
        private readonly AliyunOssSettings _ossSettings;

        public FileUploadController(OssClient ossClient, IOptions<AliyunOssSettings> ossSettings)
        {
            _ossClient = ossClient;
            _ossSettings = ossSettings.Value;
        }

        [HttpPost("upload")]
        public IActionResult UploadFile(IFormFile file)
        {
            if (file == null || file.Length == 0)
            {
                return BadRequest("请选择要上传的文件");
            }

            try
            {
                var objectKey = $"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";

                using (var stream = file.OpenReadStream())
                {
                    // 调用同步方法 PutObject(无 Async 后缀)
                    _ossClient.PutObject(_ossSettings.BucketName, objectKey, stream);
                }

                var fileUrl = $"https://{_ossSettings.BucketName}.{_ossSettings.Endpoint}/{objectKey}";

                return Ok(new
                {
                    success = true,
                    url = fileUrl,
                    message = "文件上传成功"
                });
            }
            catch (Exception ex)
            {
                return StatusCode(500, new
                {
                    success = false,
                    message = "文件上传失败",
                    error = ex.Message
                });
            }
        }
    }
}
相关推荐
one9966 分钟前
C# 的进程间通信(IPC,Inter-Process Communication)
开发语言·c#
CreasyChan9 分钟前
unity-向量数学:由浅入深详解
unity·c#
咕噜企业分发小米14 分钟前
阿里云与华为云在基因测序数据分析上哪个更强?
阿里云·数据分析·华为云
专注VB编程开发20年10 小时前
C#全面超越JAVA,主要还是跨平台用的人少
java·c#·.net·跨平台
阿里云云原生12 小时前
Android App 崩溃排查实战:如何利用 RUM 完整数据与符号化技术定位问题?
android·阿里云·云原生·rum
小猪快跑爱摄影14 小时前
【AutoCad 2025】【C#】零基础教程(四)——MText 常见属性
c#·autocad
阿里云云原生14 小时前
深度解析云监控 2.0 日志审计:统一采集、实体建模与告警溯源能力
阿里云·云原生·云监控·可观测
炼钢厂15 小时前
C#6——DateTime
c#
Lv117700816 小时前
Visual Studio中的多态
ide·笔记·c#·visual studio
wuguan_16 小时前
C#:多态函数重载、态符号重载、抽象、虚方法
开发语言·c#