1

我有一个要求,允许用户从网页打开 Word 文档并使用 MS Word 应用程序在本地进行编辑。最后他们应该能够(回发)将修改后的文档保存到服务器。

对于上述要求,我选择了 ASP.NET、C#、.NET 3.5、IIS、IE6(或更高版本)和 MS Office 2007(应该在所有工作站中)。

我开发了一个 ASP.NET Web 应用程序,它有三个 aspx 页面 Login.aspx、DocList.aspx 和 SaveDoc.aspx。

  1. Login.aspx - 身份验证/授权。(认证类型:表格)
  2. DocList.aspx - 显示/下载 word 文档。
  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 应用程序中打开。在那里,用户可以编辑文档,然后单击加载项功能区上的“发布”按钮,修改后的文档成功保存到服务器。

我的要求得到满足,并且在禁用身份验证时一切正常。

如果我启用了身份验证,加载项无法将修改后的文档上传到服务器,因为它没有经过身份验证并且无法从 IE 共享身份验证 cookie。

是否有任何解决方法/解决方案可以满足我的要求?您的帮助将不胜感激。

4

1 回答 1

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。不幸的是,我没有任何代码可以在此处读取缓存中的 cookie。

基本上,您想要做的是对该代码进行一些派生,并使用 InteretGetCookie 使用您网站域中的 cookie 创建您的 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;
    }
}
于 2009-10-16T16:09:04.560 回答