3

这是我之前在 Stackoverflow 中提出的问题之一的后续问题。

我正在尝试使用 HTTPClient 和 Sharepoint 2013 REST API 连接到 Sharepoint Online Premise 以获取“文档库”中的文档。

我在这里所做的只是一个使用 HttpClient 的简单匿名 HTTP GET 调用。

代码如下:

System.Net.Http.HttpClient _Client = new System.Net.Http.HttpClient();
_Client.BaseAddress = new Uri("https://test.sharepoint.com/_vti_bin/ListData.svc");
_Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/atom+xml"));
_Client.DefaultRequestHeaders.Add("auth_user", "test@test.onmicrosoft.com");
_Client.DefaultRequestHeaders.Add("auth_pass", "test");
_Client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
HttpResponseMessage resp = _Client.GetAsync(new Uri("https://test.sharepoint.com/_vti_bin/ListData.svc/Documents()")).Result;
string respString = resp.Content.ReadAsStringAsync().Result;

我收到以下错误:

无法从传输连接读取数据:连接已关闭。

堆栈跟踪如下:

[IOException: Unable to read data from the transport connection: The connection was closed.]
   System.Net.ConnectStream.EndRead(IAsyncResult asyncResult) +6501654
   System.Net.Http.WebExceptionWrapperStream.EndRead(IAsyncResult asyncResult) +30
   System.Net.Http.StreamToStreamCopy.BufferReadCallback(IAsyncResult ar) +54

[HttpRequestException: Error while copying content to a stream.]

[AggregateException: One or more errors occurred.]
   System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) +3569193
   System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) +73
   System.Threading.Tasks.Task`1.get_Result() +10522673
   WebApp.Test.Page_Load(Object sender, EventArgs e) in @Location
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51
   System.Web.UI.Control.OnLoad(EventArgs e) +92
   System.Web.UI.Control.LoadRecursive() +54
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +772

我浏览了各种博客/文章以获得解决问题的一些想法。但我还没有找到任何解决方案。

对此有什么想法吗?

4

3 回答 3

1

这将帮助您:

ServicePointManager.ServerCertificateValidationCallback = 
    delegate(object s, X509Certificate certificate, X509Chain chain, 
            SslPolicyErrors sslPolicyErrors) 
    { 
        return true; 
    };

放在前面request

于 2013-12-10T16:49:20.600 回答
1

我在 Visual Studio 2013 中组装了一个快速的 .NET 4.5 控制台应用程序,并且能够通过一些小的更改使您的代码正常工作,并且能够成功地进行身份验证并调用 SharePoint Online 的 REST API。

更改 #1:我添加了对两个 SharePoint 2013 客户端对象模型 (CSOM) DLL 的项目引用。您可以从此处安装 DLL:http: //www.microsoft.com/en-us/download/details.aspx?id=35585。运行安装程序并将项目引用添加到 Microsoft.SharePoint.Client.dll 和 Microsoft.SharePoint.Client.Runtime.dll。您需要这些的原因是您可以使用 SharePointOnlineCredentials 类。

更改 #2:我在您的两个异步调用中添加了“await”关键字,因为代码实际上并没有等待这些调用执行。

更改 #3:我将 HttpClient 代码修改为 (1) 使用来自 SharePointOnlineCredentials 对象的凭据,(2) 获取并使用来自 SharePoint Online 的身份验证 cookie,以及 (3) 添加一个额外的所需请求标头。

这是完整的代码片段:

Uri uri = new Uri("https://mydomain.sharepoint.com");

SharePointOnlineCredentials creds = new SharePointOnlineCredentials(
    "username@domain.com", StringUtilities.ToSecureString("YourPassword"));

string authCookie = creds.GetAuthenticationCookie(uri);
var cookies = new CookieContainer();
cookies.Add(new Cookie("FedAuth", authCookie.TrimStart("SPOIDCRL=".ToCharArray()), "", uri.Authority));

System.Net.Http.HttpClientHandler handler = new System.Net.Http.HttpClientHandler()
{
    Credentials = creds,
    CookieContainer = cookies
};

System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(handler);

client.BaseAddress = new Uri(uri, "/_vti_bin/ListData.svc");
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/atom+xml"));
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");

var response = await client.GetAsync(new Uri(uri, "/_vti_bin/ListData.svc/Documents()"));
string text = await response.Content.ReadAsStringAsync();

我运行此程序并在最后打印出“文本”变量,并从 SharePoint Online 获得了有效响应。

于 2014-01-23T21:14:15.833 回答
0

SharePoint Online 支持您尝试传递凭据的方式。

Microsoft 发布了包含 SharePointOnlineCredentials 类的SharePointOnline 客户端组件 SDK ,该类提供访问 SharePoint Online 资源的凭据。

以下示例演示了如何利用SharePointOnlineCredentials 类HttpClient 类来访问SharePoint Online

public class SPHttpClientHandler : HttpClientHandler
{
    public SPHttpClientHandler(Uri webUri, string userName, string password)
    {
        CookieContainer = GetAuthCookies(webUri, userName, password);
        FormatType = FormatType.Json;
    }


    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f");
        if(FormatType == FormatType.Json)
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        return base.SendAsync(request, cancellationToken);
    }


    /// <summary>
    /// Retrieve SPO Auth Cookies 
    /// </summary>
    /// <param name="webUri"></param>
    /// <param name="userName"></param>
    /// <param name="password"></param>
    /// <returns></returns>
    private static CookieContainer GetAuthCookies(Uri webUri, string userName, string password)
    {
        var securePassword = new SecureString();
        foreach (var c in password) { securePassword.AppendChar(c); }
        var credentials = new SharePointOnlineCredentials(userName, securePassword);
        var authCookie = credentials.GetAuthenticationCookie(webUri);
        var cookieContainer = new CookieContainer();
        cookieContainer.SetCookies(webUri, authCookie);
        return cookieContainer;
    }


    public FormatType FormatType { get; set; }
}

public enum FormatType
{
    Json,
    Xml
}

要点:SPHttpClientHandler.cs

先决条件: SharePoint Online 客户端组件 SDK中的SharePointOnlineCredentials 类用于身份验证。

用法

 var handler = new SPHttpClientHandler(webUri, userName, password);
 using (var client = new HttpClient(handler))
 {
      client.BaseAddress = webUri;
      var result = client.GetAsync("/_vti_bin/ListData.svc/Documents").Result;
      var content = result.Content.ReadAsStringAsync().Result;
 }
于 2015-04-03T21:32:07.457 回答