2009-10-16 35 views
1

我有一個要求,允許用戶使用MS Word應用程序打開網頁中的Word文檔並進行本地編輯。最後他們應該能夠(回發)將修改後的文檔保存到服務器。對於上述要求,我選擇了ASP.NET,C#,.NET 3.5,IIS,IE6(或更高版本)和MS Office 2007(應該在所有工作站中)。是否可以在IE和word插件之間共享ASP.NET會話cookie

我開發了一個ASP.NET web應用程序,它有三個aspx頁面Login.aspx,DocList.aspx和SaveDoc.aspx。

  1. Login.aspx - 身份驗證/授權。 (認證類型:表格)
  2. DocList.aspx - 顯示/下載單詞文檔。
  3. SaveDoc.aspx - 將修改後的Word文檔保存在服務器中。

而且我還開發了一個共享詞功能區插件,它可以幫助用戶通過單擊加載項中的「發佈」按鈕將修改的文檔保存到服務器。 Web客戶端已用於上載修改後的文檔。爲了將修改的文檔保存到服務器,應該在所有工作站中安裝此加載項。

string modifiedWordXml = applicationObject.ActiveDocument.WordOpenXML; 

    WebClient client = new WebClient(); 
    string serverAddress = "http://localhost:51507/DOCMGR/SaveDoc.aspx"; 
    byte[] byteArray = Encoding.UTF8.GetBytes(modifiedWordXml); 
    byte[] responceArray = client.UploadData(serverAddress, byteArray); 
    string res = Encoding.UTF8.GetString(responceArray); 
    MessageBox.Show(res,"Document Manager"); 

網頁正在顯示word文檔鏈接列表,點擊鏈接word文檔在客戶端單獨的MS Word應用程序中打開。在那裏,用戶可以編輯文檔,並在添加功能區上點擊「Puplish」按鈕,修改後的文檔成功保存到服務器。

我的要求得到滿足,並且在禁用身份驗證時一切正常。

如果我啓用了身份驗證,則加載項無法將修改後的文檔上載到服務器,因爲它未經過身份驗證,無法從IE共享身份驗證Cookie。

是否有任何解決方法/解決方案來滿足我的要求?您的幫助將不勝感激。

回答

3

您可能可以通過PInvoke GetInternetCookie獲取ASPNET會話cookie。

 [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    protected static extern bool InternetGetCookie(
     string url, 
     string name, 
     StringBuilder cookieData, 
     ref int length); 

而且這時你可以手動建立一個HttpWebRequest和添加了ASPNET會話cookie到您的CookieContainer請求對象。可能有一種方法可以將cookie添加到由WebClient創建的基礎WebRequest,如果可以的話,您可以使用它。

希望這會有所幫助。

編輯:

基本上這裏是我使用我的HttpWebRequest設置在IE瀏覽器cookie緩存餅乾的代碼。不幸的是,我沒有任何代碼能夠在這裏讀取緩存中的cookie。

基本上你想要做的是採取一些派生的代碼,並使用InteretGetCookie從您的網站的域創建CookieCollection對象。你必須手動解析這些。然後在您的HttpWebRequest上,您可以使用您使用InternetGetCookie從您的域中讀取的cookie,並將它們傳遞到您創建的CookieContainer中。

public class HttpWebConnection 
{ 
    [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    protected static extern bool InternetSetCookie(
     string url, 
     string name, 
     string cookieData); 

    [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    protected static extern bool InternetGetCookie(
     string url, 
     string name, 
     StringBuilder cookieData, 
     ref int length); 

    public HttpWebConnection() 
    { 
     Cookies = new CookieContainer(); 
     AutoRedirect = false; 
    } 

    public HttpWebConnection(string baseAddress) 
     : this() 
    { 
     BaseAddress = baseAddress; 
     BaseUri = new Uri(BaseAddress); 
    } 

    public bool AutoRedirect { get; set; } 

    public Uri BaseUri { get; private set; } 

    public string BaseAddress { get; private set; } 

    public CookieContainer Cookies { get; private set; } 

    public virtual HttpWebResponse Send(string method, Uri uri) 
    { 
     return Send(method, uri, null, false); 
    } 

    public virtual HttpWebResponse Send(string method, Uri uri, string post, bool authenticating) 
    { 
     Uri absoluteUri = null; 
     if (uri.IsAbsoluteUri) 
     { 
      absoluteUri = uri; 
     } 
     else 
     { 
      absoluteUri = new Uri(BaseUri, uri); 
     } 

     HttpWebRequest request = WebRequest.Create(absoluteUri) as HttpWebRequest; 
     request.CookieContainer = Cookies; 
     request.Method = method; 
     if (method == "POST") 
     { 
      request.ContentType = "application/x-www-form-urlencoded"; 
     } 

     request.AllowAutoRedirect = false; 

     if (!string.IsNullOrEmpty(post)) 
     { 
      Stream requestStream = request.GetRequestStream(); 
      byte[] buffer = Encoding.UTF8.GetBytes(post); 
      requestStream.Write(buffer, 0, buffer.Length); 
      requestStream.Close(); 
     } 

     HttpWebResponse response = null; 

     response = request.GetResponse() as HttpWebResponse; 

     foreach (Cookie cookie in response.Cookies) 
     { 
      bool result = InternetSetCookie(BaseAddress, cookie.Name, cookie.Value); 
      if (!result) 
      { 
       int errorNumber = Marshal.GetLastWin32Error(); 
      } 
     } 

     if (AutoRedirect && (response.StatusCode == HttpStatusCode.SeeOther 
        || response.StatusCode == HttpStatusCode.RedirectMethod 
        || response.StatusCode == HttpStatusCode.RedirectKeepVerb 
        || response.StatusCode == HttpStatusCode.Redirect 
        || response.StatusCode == HttpStatusCode.Moved 
        || response.StatusCode == HttpStatusCode.MovedPermanently)) 
     { 
      string uriString = response.Headers[HttpResponseHeader.Location]; 
      Uri locationUri; 
      //TODO investigate if there is a better way to detect for a relative vs. absolute uri. 
      if (uriString.StartsWith("HTTP", StringComparison.OrdinalIgnoreCase)) 
      { 
       locationUri = new Uri(uriString); 
      } 
      else 
      { 
       locationUri = new Uri(this.BaseUri, new Uri(uriString)); 
      } 

      response = Send("GET", locationUri); 
     } 

     return response; 
    } 
} 
+0

謝謝你的幫助。我改變了我的代碼,使用HttpWebRequest而不是WebClient,並根據請求對象將一個ASPNET會話cookie添加到CookieContainer。仍然沒有運氣。爲了您的參考,我附上下面的代碼。如果我缺少任何東西,請告訴我。 HttpWebRequest請求=(HttpWebRequest)WebRequest.Create(「http://SERVERIP/DOCMGR/SaveDoc.aspx」); Uri uri = new Uri(「http:// SERVERIP」); request.CookieContainer = GetUriCookieContainer(uri); request.Method =「POST」; 注意:HTTP://會在本帖中被刪除 – afin 2009-10-21 19:07:54

+0

我讀了一篇msdn文章,指出「InternetGetCookie不會將服務器標記爲非腳本的Cookie與Set-Cookie頭中的」HttpOnly「屬性配合使用。 MSDN URL:http://msdn.microsoft.com/en-us/library/aa384710%28VS.85%29.aspx 由於我們使用表單身份驗證,cookie默認情況下具有「HttpOnly」屬性,InternetGetCookie不會返回Cookie。有什麼解決方法嗎?提前致謝。 – afin 2009-10-21 21:20:17

+0

這是一個愚蠢的問題,但你可以在你的網站上創建一個cookie,當你認證的用戶沒有被標記爲HttpOnly時,你可以共享進行認證嗎?然後,而不是尋找.NET會話cookie,你可以尋找你自己的是在用戶認證後創建的? – 2009-10-21 21:55:47

相關問題