在.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
                });
            }
        }
    }
}
相关推荐
缺点内向9 小时前
C#: 高效移动与删除Excel工作表
开发语言·c#·.net·excel
周杰伦fans11 小时前
.NET Core WebAPI 中 HTTP 请求方法详解:从新手到精通
网络协议·http·.netcore
yue00811 小时前
C# 分部类读取学生信息
开发语言·c#
聪明努力的积极向上11 小时前
【C#】事件简单解析
开发语言·c#
qq_124987075312 小时前
基于C#的贵州省黔北地区乡村避暑生活共享平台设计与实现(源码+论文+部署+安装)
c#·毕业设计·asp.net·生活
toooooop815 小时前
阿里云 CDN + 静态资源(图片 / JS/CSS)缓存优化
阿里云·cdn
阿里云通信17 小时前
个人开发者短信验证码接入指南-阿里云
阿里云·云计算·短信验证码·个人开发者·短信认证
LateFrames18 小时前
C# 中,0.1 在什么情况下不等于 0.1 ?
开发语言·c#
zz-zjx18 小时前
云计算产品-介绍--网络/CDN篇
阿里云·云计算