【问题标题】:C# Open web page in default browser with post dataC#在默认浏览器中打开网页并发布数据
【发布时间】:2012-04-10 14:51:11
【问题描述】:

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

我正在用 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> 提交按钮以防万一)而且看起来有点笨拙,所以我仍然真的希望这里有人会出现有更好的东西。

【问题讨论】:

    标签: c# http-post


    【解决方案1】:

    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 点。您无法点击浏览器中的后退按钮再次登录,因为哈希已消失。

    【讨论】:

      【解决方案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 并在默认浏览器中打开。

      【讨论】:

        【解决方案3】:

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

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

        编辑:

        plain ASMX web service 至少应该可以帮助您入门。您可以右键单击您的项目并选择添加服务引用以生成调用服务的代理代码。

        【讨论】:

        • 谢谢!但不幸的是,目前这远远超出了我的范围。我会做一些研究,看看我是否可以得到类似的东西来工作并发布我的结果。
        • 好消息!这不再超出我的范围,所以我接受了你的回答(晚了 4 年)!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-19
        • 2017-10-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多