在.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
                });
            }
        }
    }
}
相关推荐
G311354227310 小时前
从零开始 通义千问大模型本地化到阿里云通义千问API调用
阿里云·云计算
Triumph++11 小时前
电器模C#汇控电子继块驱动(Modbus协议)
c#·visual studio·c#串口通信
咩图14 小时前
C#创建AI项目
开发语言·人工智能·c#
周杰伦fans15 小时前
C# - Task 是什么?想象一下你在餐厅点餐
服务器·开发语言·c#
一只小小汤圆17 小时前
简化点集合 道格拉斯-普克算法(Douglas-Peucker Algorithm)
c#·occ
scixing17 小时前
函数式编程 第八讲 循环者,递归也
开发语言·c#
屠夫18 小时前
SqlSugar的简单使用
c#
dotent·1 天前
C#基于WPF UI框架的通用基础上位机测试WPF框架
ui·c#·wpf
合作小小程序员小小店1 天前
桌面开发,超市管理系统开发,基于C#,winform,sql server数据库
开发语言·数据库·sql·microsoft·sqlserver·c#