2009-10-16 34 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

相关问题