是否可以在 IE 和 Word 附加组件之间共享 ASP.NET 会话 cookie

发布于 2024-08-07 19:27:46 字数 1207 浏览 3 评论 0原文

我需要允许用户从网页打开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 文档保存在服务器中。

我还开发了一个共享Word Ribbon插件,它可以帮助用户通过单击插件中的“发布”按钮将修改后的文档保存到服务器。已使用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。

有没有任何解决方法/解决方案可以满足我的要求?我们将非常感谢您的帮助。

I have a requirement to allow users to open word document from web page and edit locally by using MS Word application. finally they should be able to (post back)save the modified document to server.

For the above requirement I have chosen ASP.NET, C#, .NET 3.5, IIS, IE6 (or above) and MS Office 2007 (should be in all workstations).

I have developed a ASP.NET web application, which has three aspx pages Login.aspx, DocList.aspx and SaveDoc.aspx.

  1. Login.aspx - Authentication/Authorization. (Authentication type:Forms)
  2. DocList.aspx - To display/Download word documents.
  3. SaveDoc.aspx - To save modified word document in server.

And also I developed a shared word ribbon add-in, which helps the user save the modified document to server by clicking "Publish" button in add-in. web client has been used to upload the modified document. In order to save the modified document to server, this add-in should be installed in all workstations.

    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");

Web page is displaying list of word document links, upon clicking on the link the word document is open up in separate MS Word application in client. There, User can edit the document and upon clicking "Puplish" button on add-in ribbon, modified document successfully saved to server.

My requirement is satisfied and everything is working fine when authentication is disabled.

If I enabled Authentication, add-in failed to upload the modified document to server as it is not authenticated and could not share the Authentication cookies from the IE.

Is there is any workaround/solution to satisfy my requirement? Your help will be greatly appreciate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮世清欢 2024-08-14 19:27:46

您可以 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;
    }
}

You may be able to PInvoke GetInternetCookie in order to get the ASPNET session cookie.

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

And then you can manually build up an HttpWebRequest and add a the ASPNET session cookie to a CookieContainer on your request object. There may be a way to add cookies to the underlying WebRequest created by the WebClient, if so you could use it instead.

Hope this helps.

EDIT:

Basically here is the code that I am using on my HttpWebRequest to set cookies in the IE cookie cache. Unfortunately I don't have any code that provides the ability to read the cookie in the cache here.

Basically what you'd want to do is take some derivation of this code and create your CookieCollection object with the cookies from the domain of your website using InteretGetCookie. You'll have to parse these manually. Then on your HttpWebRequest you can use the cookies you read from your domain using InternetGetCookie and pass them in the CookieContainer you created.

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文