You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HttpClient上传文件至SharePoint Online Drive时程序无响应求助

问题分析与解决方案

核心原因:异步操作未被主线程等待,导致程序提前退出

你的控制台程序中,若Main方法是普通void类型,执行到await client.PutAsync时,异步操作会在后台运行,但主线程不会等待其完成,直接走到代码末尾后程序正常退出(返回码0),因此看不到任何日志输出,文件上传也未完成。

另外代码存在一处明显错误:你给获取令牌时使用的content对象设置了ContentType,而非要上传的fileContent,这会导致请求的内容类型不正确,即便解决了异步等待问题,也可能上传失败。

修复步骤

  • 将Main方法改为异步类型:把控制台程序的Main方法声明为async Task Main(),确保主线程会等待所有异步操作完成。
  • 替换同步阻塞的.Result为await:避免同步阻塞引发死锁,同时保证异步流程的正确性。
  • 修正ContentType的赋值对象:给fileContent设置正确的内容类型。
  • 添加控制台暂停(可选):防止程序执行完成后直接关闭控制台,方便查看输出结果。

修正后的完整代码示例

using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Newtonsoft.Json;

class Program
{
    static async Task Main(string[] args)
    {
        var tokenEndpoint = "你的令牌请求端点";
        var content = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("grant_type", "client_credentials"),
            // 补充client_id、client_secret等必要参数
        });

        var httpClient = new HttpClient();
        var response = await httpClient.PostAsync(tokenEndpoint, content);
        response.EnsureSuccessStatusCode(); // 确保令牌请求成功
        var token = await response.Content.ReadAsStringAsync();
        var accessToken = JsonConvert.DeserializeObject<AccessToken>(token).access_token;

        var fileName = @"c:\data\sample.txt";
        var fileNameEndpoint = @"https://graph.microsoft.com/v1.0/drives/{driveID}/root:/General/sample.txt:/content";

        using (HttpClient client = new HttpClient())
        {
            using (FileStream fileStream = File.OpenRead(fileName))
            {
                var fileContent = new StreamContent(fileStream);
                fileContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                try
                {
                    var response1 = await client.PutAsync(fileNameEndpoint, fileContent);
                    if (response1.IsSuccessStatusCode)
                    {
                        Console.WriteLine("文件上传成功!");
                    }
                    else
                    {
                        // 读取详细错误信息,便于排查问题
                        var errorContent = await response1.Content.ReadAsStringAsync();
                        Console.WriteLine($"错误:{response1.StatusCode} - {response1.ReasonPhrase}\n详情:{errorContent}");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine($"发生异常:{e.Message}\n堆栈跟踪:{e.StackTrace}");
                    throw;
                }
            }
        }

        Console.WriteLine("按任意键退出...");
        Console.ReadKey();
    }
}

public class AccessToken
{
    public string access_token { get; set; }
    // 可添加expires_in等其他返回属性
}

额外建议

  • 获取令牌后添加response.EnsureSuccessStatusCode()检查请求是否成功,避免使用无效令牌调用Graph API。
  • 上传失败时读取响应的详细内容,能获取Graph API返回的具体错误信息,大幅提升排查效率。

内容的提问来源于stack exchange,提问作者gilesrpa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:35:25