9

我确信这之前一定已经回答过,但我找不到解决方案,所以我认为我可能会误解其他人的解决方案或试图做一些愚蠢的事情,但我们开始吧。

我正在用 C# 为 Outlook 2010 编写一个加载项,用户可以在其中单击功能区中的按钮并将电子邮件内容提交到网站。当他们单击按钮时,网站应在默认浏览器中打开,从而允许他们查看刚刚提交的内容并在网站上与之交互。我可以使用 URL 中的查询字符串执行此操作:

System.Diagnostics.Process.Start("http://www.test.com?something=value");

但是可以提交的数据量的限制和凌乱的 URL 使我无法遵循这种方法。我想为此使用 HTTP POST,因为它显然更合适。但是,我发现执行此操作的方法似乎在提交帖子数据后无法在浏览器中打开页面:

http://msdn.microsoft.com/en-us/library/debx8sh9.aspx

总结;用户需要能够单击 Outlook 功能区中的按钮,打开 Web 浏览器并显示通过 POST 提交的电子邮件的内容。

编辑:

是的,我找到了一种方法,它非常丑陋,但它有效!只需创建一个临时 .html 文件(然后按上述方式启动),其中包含一个包含所有数据隐藏字段的表单,并在使用 JavaScript 加载页面时提交它。

我不太喜欢这个解决方案,因为它依赖于 JavaScript(我有一个<noscript>提交按钮以防万一)而且看起来有点笨拙,所以我仍然真的希望这里有人能想出更好的东西。

4

3 回答 3

3

Dropbox 客户端的操作方式与您在 EDIT 中提到的方式相同。但它也做了一些混淆,即它用通过 URL 提交的散列对数据进行异或。

以下是 Dropbox 的操作步骤:

  1. 应用内:创建可用于在 dropbox.com 上进行授权的令牌。
  2. 应用内:将令牌转换为十六进制字符串 (A)。
  3. 应用内:创建一个相同长度的安全随机十六进制字符串 (B)。
  4. 应用内:计算 C = A XOr B。
  5. 应用内:创建具有以下功能的临时 HTML 文件:
  6. 包含值 B 的隐藏输入字段。
  7. 提交表单,其中包含登录 dropbox.com 所需的隐藏输入字段。
  8. 一个 JS 函数,它从 URI 读取哈希,与 B 进行异或并将结果写入提交表单的隐藏字段。
  9. 从 URI 中删除哈希。
  10. 提交表格。
  11. 应用内:使用标准浏览器打开临时 HTML 文件,并将 C 作为哈希添加到 URI 的末尾。

现在,如果您的浏览器打开 HTML 文件,它会根据隐藏的输入字段和 URI 中的哈希计算身份验证令牌并打开 dropbox.com。由于第 5.4 点。您无法点击浏览器中的后退按钮再次登录,因为哈希已消失。

于 2015-12-07T10:34:12.617 回答
2

这已经晚了八年,但这里有一些代码很好地说明了这个过程:

string tempHTMLLocation = "some_arbitrary_location" + "/temp.html";
string url = https://your_desired_url.com";

    // create the temporary html file
    using (FileStream fs = new FileStream(tempHTMLLocation, FileMode.Create)) { 
        using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8)) { 
            w.WriteLine("<body onload=\"goToLink()\">");
            w.WriteLine("<form id=\"form\" method=\"POST\" action=\"" + url + "\">");
            w.WriteLine("<input type=\"hidden\" name=\"post1\" value=\"" + post_data1 + "\">");
            w.WriteLine("<input type=\"hidden\" name=\"post2\" value=\"" + post_data2 + "\">");
            w.WriteLine("</form>");
            w.WriteLine("<script> function goToLink() { document.getElementById(\"form\").submit(); } </script>");
                        w.WriteLine("</body>");
        } 
    }

    // launch the temp html file
    var launchProcess = new ProcessStartInfo {
        FileName = tempHTMLLocation,
        UseShellExecute = true
    };
    Process.Start(launchProcess);

    // delete temp file but add delay so that Process has time to open file
    Task.Delay(1500).ContinueWith(t=> File.Delete(tempHTMLLocation));

打开页面后,onload() JS 脚本立即提交表单,该表单将数据发布到 url 并在默认浏览器中打开。

于 2021-03-29T15:21:14.467 回答
1

我不确定我是否会以这种方式构建解决方案。相反,我会将所有数据发布到 Web 服务(使用 HttpWebRequest,如 @Loci 所述,或者仅使用 Visual Studio 导入服务),该服务会将数据存储在数据库中(可能处于待处理状态)。然后将用户(使用您的 Process.Start 方法)引导到一个页面,该页面将显示待处理的帮助票,这将允许他们批准或放弃该票。

这听起来像是更多的工作,但它应该清理你正在尝试做的架构。另外,您还有一个额外的好处,那就是不必担心如何从客户端触发表单发布。

编辑:

一个普通的 ASMX Web 服务至少应该让你开始。您可以右键单击您的项目并选择添加服务引用以生成用于调用服务的代理代码。

于 2012-04-12T12:05:27.333 回答