2013-11-04 78 views
3

这是Stackoverflow中my earlier question之一的后续问题。使用C#Sharepoint 2013 REST API调用

我试图连接到SharePoint Online的前提利用HttpClient的和SharePoint 2013 REST API来获取“文档库”中的文件。

所有我做这里是使用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", "[email protected]"); 
_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 

我已经通过各种blogs/articles去得到一些想法来解决issue.But我cudn't找到任何解决办法呢。

对此有何看法?

+0

您是否正在从ASP.NET网站执行此操作?我怀疑你的.Result电话有些奇怪。你有没有尝试过使用异步/等待? –

+0

是的,我正在从ASP.NET网站执行此操作。 – Bisileesh

回答

1

这将帮助你:

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

request之前所说的那样。

1

我放在一起快速.NET 4.5的控制台应用程序在Visual Studio 2013能够得到你的代码有一些小的改动工作,我能够成功进行身份验证,并调用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联机认证的cookie,以及(3)添加真实需要一个附加的请求头。

下面是完整的代码片段:

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

SharePointOnlineCredentials creds = new SharePointOnlineCredentials(
    "[email protected]", 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的有效响应。

0

你试图传递凭证的方式是不 SharePoint Online的支持。

微软发布SharePointOnline Client Components SDK包含SharePointOnlineCredentials class提供凭据访问SharePoint Online资源。

下面的例子演示了如何利用SharePointOnlineCredentials classHttpClient class才能访问的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 
} 

Gist: SPHttpClientHandler.cs

Prerequisites: SharePointOnlineCredentials class from SharePoint Online Client Components SDK is used for authentication.

使用

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; 
} 
相关问题