无法验证来自 .NET Core 的 SharePoint REST 或 CSOM 调用
Unable to authenticate SharePoint REST or CSOM calls from .NET Core
我在使用 CSOM 和 REST 服务从 .NET Core 控制台应用程序访问 SharePoint 时遇到问题。
首先,我创建了一个面向 .NET Framework 4.6.1 的控制台应用程序,安装了 Microsoft.SharePointOnline.CSOM nuget 包,并添加了两个示例方法以使用硬编码的用户凭据连接到 SharePoint。这行得通。
public static void CsomCall()
{
var password = "password";
var securePassword = new SecureString();
foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);
using (ClientContext context = new ClientContext("https://siteurl"))
{
context.Credentials = new SharePointOnlineCredentials("user@domain", securePassword);
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
Console.WriteLine(web.Title);
}
}
private static void RestCall()
{
var password = "password";
var securePassword = new SecureString();
foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);
var credentials = new SharePointOnlineCredentials("user@domain", securePassword);
using (WebClient client = new WebClient())
{
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
client.Credentials = credentials;
client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
var content = client.DownloadString("https://siteurl/_api/web/lists");
Console.WriteLine(content);
}
}
然后我创建了一个 .NET Core 控制台应用程序并复制了上面的方法。我了解 .NET Core 尚不支持 SharePoint CSOM,因此我使用了建议的解决方法 here 并手动引用了 Microsoft.SharePoint.Client.Portable.dll、Microsoft.SharePoint.Client.Runtime.Portable.dll 和 Microsoft.SharePoint.Client.Runtime.Windows.dll.
我必须进行一些更改才能编译代码:
.ExecuteQueryAsync()
而不是 .ExecuteQuery()
var credentials = new SharePointOnlineCredentials("user@domain", password);
注意,密码是 Microsoft.SharePoint.Client.Runtime.Portable.
中的纯字符串
当 运行 CsomCall 访问时失败 web.Title:
Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException: 'The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.'
当 运行 RestCall 失败并在 client.DownloadString 上出现错误:
System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'
是否可以设置 SharePointOnlineCredentials 以使用 .NET Core?对堆栈溢出的搜索表明这应该是可能的,但我似乎无法让它工作。
最终我们想使用 ASP.NET Core 构建一个 Web API 服务来为内部用户生成文档(从 SharePoint 读取文档模板,生成新文档并保存回 SharePoint)。现在使用 CSOM 或 REST,并在 Windows OS 上使用 运行。
REST 调用错误。您必须使用凭据获取令牌。此外,WebClient 大部分已被弃用,请改用 HttpClient class。
看这个例子:
public const string BaseUri = "https://example.sharepoint.com";
private static HttpClient _client;
public static void Initialize()
{
SharePointOnlineCredentials currentCredentials = GetCredentialsHere();
var handler = new HttpClientHandler
{
Credentials = currentCredentials
};
_client = new HttpClient(handler);
// you are missing this line
handler.CookieContainer.SetCookies(BaseUri, currentCredentials.GetAuthenticationCookie(BaseUri));
_client.BaseAddress = BaseUri;
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.MaxResponseContentBufferSize = 2147483647;
}
我在使用 CSOM 和 REST 服务从 .NET Core 控制台应用程序访问 SharePoint 时遇到问题。
首先,我创建了一个面向 .NET Framework 4.6.1 的控制台应用程序,安装了 Microsoft.SharePointOnline.CSOM nuget 包,并添加了两个示例方法以使用硬编码的用户凭据连接到 SharePoint。这行得通。
public static void CsomCall()
{
var password = "password";
var securePassword = new SecureString();
foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);
using (ClientContext context = new ClientContext("https://siteurl"))
{
context.Credentials = new SharePointOnlineCredentials("user@domain", securePassword);
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
Console.WriteLine(web.Title);
}
}
private static void RestCall()
{
var password = "password";
var securePassword = new SecureString();
foreach (var c in password.ToCharArray()) securePassword.AppendChar(c);
var credentials = new SharePointOnlineCredentials("user@domain", securePassword);
using (WebClient client = new WebClient())
{
client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
client.Credentials = credentials;
client.Headers.Add(HttpRequestHeader.ContentType, "application/json;odata=verbose");
client.Headers.Add(HttpRequestHeader.Accept, "application/json;odata=verbose");
var content = client.DownloadString("https://siteurl/_api/web/lists");
Console.WriteLine(content);
}
}
然后我创建了一个 .NET Core 控制台应用程序并复制了上面的方法。我了解 .NET Core 尚不支持 SharePoint CSOM,因此我使用了建议的解决方法 here 并手动引用了 Microsoft.SharePoint.Client.Portable.dll、Microsoft.SharePoint.Client.Runtime.Portable.dll 和 Microsoft.SharePoint.Client.Runtime.Windows.dll.
我必须进行一些更改才能编译代码:
.ExecuteQueryAsync()
而不是.ExecuteQuery()
var credentials = new SharePointOnlineCredentials("user@domain", password);
注意,密码是 Microsoft.SharePoint.Client.Runtime.Portable. 中的纯字符串
当 运行 CsomCall 访问时失败 web.Title:
Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException: 'The property or field 'Title' has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.'
当 运行 RestCall 失败并在 client.DownloadString 上出现错误:
System.Net.WebException: 'The remote server returned an error: (401) Unauthorized.'
是否可以设置 SharePointOnlineCredentials 以使用 .NET Core?对堆栈溢出的搜索表明这应该是可能的,但我似乎无法让它工作。
最终我们想使用 ASP.NET Core 构建一个 Web API 服务来为内部用户生成文档(从 SharePoint 读取文档模板,生成新文档并保存回 SharePoint)。现在使用 CSOM 或 REST,并在 Windows OS 上使用 运行。
REST 调用错误。您必须使用凭据获取令牌。此外,WebClient 大部分已被弃用,请改用 HttpClient class。
看这个例子:
public const string BaseUri = "https://example.sharepoint.com";
private static HttpClient _client;
public static void Initialize()
{
SharePointOnlineCredentials currentCredentials = GetCredentialsHere();
var handler = new HttpClientHandler
{
Credentials = currentCredentials
};
_client = new HttpClient(handler);
// you are missing this line
handler.CookieContainer.SetCookies(BaseUri, currentCredentials.GetAuthenticationCookie(BaseUri));
_client.BaseAddress = BaseUri;
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.MaxResponseContentBufferSize = 2147483647;
}