2010-01-05 41 views
0

我有如下一個WebDAV功能:檢查MOSS資源存在產生意想不到401的

的行爲是完全出乎意料....

當我第一次運行該功能,並通過一個URL的資源(文件夾在SharePoint中)不存在,我得到一個404預計。然後,我使用另一個函數來使用此方法中的SAME憑證創建資源。可是...

但是在第二次運行後,該資源已創建沒有問題 - 當我檢查是否存在資源,現在我得到一個401

請告訴我,這裏要注意重要的是,同樣的憑據用於檢查401和創建文件夾,所以顯然憑證很好...

所以它必須是別的東西....我想要做的就是檢查資源是否存在於SharePoint ....任何想法如何改進這個功能?或任何理論,爲什麼它給這個401 ...

private bool MossResourceExists(string url) 
     { 
      var request = (HttpWebRequest)WebRequest.Create(url); 
      request.Method = "HEAD"; 

      // Create a new CredentialCache object and fill it with the network 
      // credentials required to access the server. 
      var myCredentialCache = new CredentialCache(); 
      if (!string.IsNullOrEmpty(this.Domain)) 
      { 
       myCredentialCache.Add(new Uri(url), 
       "NTLM", 
       new NetworkCredential(this.Username , this.Password , this.Domain) 
       ); 
      } 
      else 
      { 
       myCredentialCache.Add(new Uri(url), 
       "NTLM", 
       new NetworkCredential(this.Username , this.Password) 
       ); 
      } 

      request.Credentials = myCredentialCache; 

      try 
      { 
       request.GetResponse(); 
       return true; 

      } 
      catch (WebException ex) 
      { 
       var errorResponse = ex.Response as HttpWebResponse; 

       if (errorResponse != null) 
        if (errorResponse.StatusCode == HttpStatusCode.NotFound) 
        { 
         return false; 
        } 
        else 
        { 
         throw new Exception("Error checking if URL exists:" + url + ";Status Code:" + errorResponse.StatusCode + ";Error Message:" + ex.Message) ; 
        } 
      } 
      return true; 
     } 

我唯一的線索就是使用http://mysite.com/mydoclib/mytoplevelfolder它工作的時候....任何子文件自動給401的....

回答

1

問題是你無法將包含文件夾的整個url傳遞給CredentialCache.Add()方法。

例如:
http://MyHost/DocumentLibrary/folder1/folder2不會作爲烏里到Add()方法的工作,但
http://MyHost/DocumentLibrary/將工作。

我猜想在SharePoint中缺少文件夾級權限功能是造成這種情況的原因。或者SharePoint處理文件夾的方式。

您可以做的是將方法中的參數分開以接受基礎URL(包括文檔庫/列表)和文件夾名稱參數。 CredentialCache獲取基礎URL,請求對象獲取完整的URL。

另一種方法是使用

request.Credentials = System.Net.CredentialCache.DefaultCredentials; 

憑據,而不是。並且,如果您想使用另一個帳戶而不是正在執行的帳戶,則必要時進行模擬。

第三個變體是嘗試將驗證類型設置爲Kerberos而不是NTLM。

這是我的測試代碼。我能夠重現問題,如果我用您的代碼替換問題,並且此代碼適用於我。

static void Main(string[] args) 
{ 
    bool result = MossResourceExists("http://intranet/subtest/content_documents/", "testfolder/testfolder2"); 
} 

private static bool MossResourceExists(string baseUrl, string folder) 
{ 
    string completeUrl = baseUrl + folder; 

    var request = (HttpWebRequest)WebRequest.Create(completeUrl); 
    request.Method = "HEAD"; 

    // Create a new CredentialCache object and fill it with the network 
    // credentials required to access the server. 
    var myCredentialCache = new CredentialCache(); 
    if (!string.IsNullOrEmpty(Domain)) 
    { 
    myCredentialCache.Add(new Uri(baseUrl), 
    "NTLM", 
    new NetworkCredential(Username, Password, Domain) 
    ); 
    } 
    else 
    { 
    myCredentialCache.Add(new Uri(baseUrl), 
    "NTLM", 
    new NetworkCredential(Username, Password) 
    ); 
    } 

    request.Credentials = myCredentialCache; 
    //request.Credentials = System.Net.CredentialCache.DefaultCredentials; 

    try 
    { 
    WebResponse response = request.GetResponse(); 
    return true; 
    } 
    catch (WebException ex) 
    { 
    var errorResponse = ex.Response as HttpWebResponse; 

    if (errorResponse != null) 
     if (errorResponse.StatusCode == HttpStatusCode.NotFound) 
     { 
     return false; 
     } 
     else 
     { 
     throw new Exception("Error checking if URL exists:" + completeUrl + ";Status Code:" + errorResponse.StatusCode + ";Error Message:" + ex.Message); 
     } 
    } 
    return true; 
} 

希望這會有所幫助。

+0

+1有關通過憑證的信息,但我試圖重新路由憑據,仍然存在問題。 – 2010-01-06 08:51:37

+0

JL,我能夠用你的代碼重現。我發佈了我的修改後的代碼。對你起作用嗎? – 2010-01-06 11:48:40

+0

確實非常有趣,我決定用PROPFIND來代替,但是你的答案確實提供了對問題的洞察力,所以被接受的答案!再次感謝。 – 2010-01-07 11:20:21