You need to enable JavaScript to run this app. C#通过Selenium登录微软账号编辑SharePoint Excel报405错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

C#通过Selenium登录微软账号编辑SharePoint Excel报405错误如何解决

问题根因

你遇到的问题同时包含两个错误点:

  • 第一个是上传地址错误:你当前传入的https://teamsite.xxxxxx.com/:x:/s/test597/xxxxxx-xxxxxxxxx_xxxxxx?e=xxxxx是SharePoint生成的文件预览共享链接,该端点仅支持GET请求,不支持PUT上传操作,这是触发405 Method Not Allowed的核心原因。
  • 第二个是身份认证信息缺失:你当前用的CredentialCache.DefaultCredentials是本地Windows凭据,和Selenium模拟登录得到的微软账号身份完全无关,就算地址正确也会被鉴权拒绝。

修复步骤

  1. 修正上传路径:将共享链接替换为SharePoint站点内文件的真实路径,格式为https://<站点域名>/sites/<站点名>/<文档库名>/<目标文件名>.xlsx,比如你要上传到test597站点的共享文档库,路径就是https://teamsite.xxxxxx.com/sites/test597/Shared Documents/exceltest.xlsx
  2. 导出Selenium登录后的Cookie:完成微软账号登录后,先导航到你的SharePoint站点根地址,确保站点相关Cookie全部加载完成,再将Selenium的Cookie集合转换为WebRequest可用的CookieContainer对象
  3. 修改上传方法,传入CookieContainer完成身份认证

完整修改后的代码示例

using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using OtpNet;
using System.Net;
using System.IO;

static void Main(string[] args)
{
    string base32Secret = "xxxxxxx";
    var secret = Base32Encoding.ToBytes(base32Secret);
    var totp = new Totp(secret);
    var code = totp.ComputeTotp();
    Console.WriteLine(code);

    IWebDriver driver = new FirefoxDriver();
    driver.Navigate().GoToUrl("https://myaccount.microsoft.com/");

    // 用户名输入
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    wait.Until(ExpectedConditions.ElementIsVisible(By.Id("i0116")));
    driver.FindElement(By.Id("i0116")).SendKeys("xxxxx");
    driver.FindElement(By.Id("idSIButton9")).Click();

    // 密码输入
    wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    wait.Until(ExpectedConditions.ElementIsVisible(By.Id("i0118")));
    driver.FindElement(By.Id("i0118")).SendKeys("xxxxxxx");
    driver.FindElement(By.Id("idSIButton9")).Click();

    // OTP输入
    wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    wait.Until(ExpectedConditions.ElementIsVisible(By.Id("idTxtBx_SAOTCC_OTC")));
    driver.FindElement(By.Id("idTxtBx_SAOTCC_OTC")).SendKeys(code);
    driver.FindElement(By.Id("idSubmit_SAOTCC_Continue")).Click();

    // 保持登录确认
    wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    wait.Until(ExpectedConditions.ElementIsVisible(By.Id("idSIButton9")));
    driver.FindElement(By.Id("idSIButton9")).Click();

    // 新增:导航到SharePoint站点加载站点Cookie
    driver.Navigate().GoToUrl("https://teamsite.xxxxxx.com/s/test597/");
    wait.Until(d => d.Title.Contains("test597")); // 等待站点加载完成

    // 新增:导出Selenium Cookie到CookieContainer
    CookieContainer cookieContainer = new CookieContainer();
    foreach (var cookie in driver.Manage().Cookies.AllCookies)
    {
        cookieContainer.Add(new System.Net.Cookie(
            cookie.Name,
            cookie.Value,
            cookie.Path,
            cookie.Domain
        ));
    }
    driver.Quit(); // 登录完成可以关闭浏览器了

    // 修正:传入CookieContainer,替换为真实的上传路径
    PublishWorkbook(
        @"C:\test\exceltest.xlsx", 
        "https://teamsite.xxxxxx.com/sites/test597/Shared Documents/exceltest.xlsx",
        cookieContainer
    );
}

// 新增:方法增加CookieContainer参数
static void PublishWorkbook(string LocalPath, string SharePointPath, CookieContainer cookieContainer)
{
    WebResponse response = null;
    try
    {
        WebRequest request = WebRequest.Create(SharePointPath);
        // 删掉原来的DefaultCredentials,替换为CookieContainer
        request.CookieContainer = cookieContainer;
        request.Method = "PUT";

        byte[] buffer = new byte[1024];
        using (Stream stream = request.GetRequestStream())
        using (FileStream fsWorkbook = File.Open(LocalPath, FileMode.Open, FileAccess.Read))
        {
            int i = fsWorkbook.Read(buffer, 0, buffer.Length);
            while (i > 0)
            {
                stream.Write(buffer, 0, i);
                i = fsWorkbook.Read(buffer, 0, buffer.Length);
            }
        }
        response = request.GetResponse();
    }
    finally
    {
        response?.Close(); // 增加空判断避免空引用异常
    }
}

注意事项

  • 确保你登录的微软账号对目标SharePoint文档库有编辑/上传权限
  • 如果要上传到子文件夹,直接在路径里拼接子文件夹名称即可
  • 如果需要避免覆盖已有文件,可以在请求头中添加If-Match: *或者对应文件的ETag值控制行为

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 18:06:04