在 ASP.NET 中,实现非 ASP.NET

分享于 

9分钟阅读

Web开发

  繁體 雙語

当与网络上的一些资源交互时,有时会提供一小段HTML代码。 例如要在你的网站上插入PayPal按钮,PayPal提供了可能看起来像这样的HTML代码。

<formaction="https://www.paypal.com/cgi-bin/webscr"method="post"><inputtype="hidden"name="cmd"value="_xclick"><inputtype="hidden"name="business"value="bob@domain.com"><inputtype="hidden"name="lc"value="US"><inputtype="hidden"name="item_name"value="Widget"><inputtype="hidden"name="amount"value="100.00"><inputtype="hidden"name="currency_code"value="USD"><inputtype="hidden"name="bn"value="PP-BuyNowBF:btn_buynow_LG.gif:NonHostedGuest"><inputtype="image"src="https://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"border="0"name="submit"alt=""><imgalt=""border="0"src="https://www.paypal.com/en_US/i/scr/pixel.gif"width="1"height="1"></form>
插入PayPal按钮的HTML代码

这里代码段定义了 <窗体> 还有几个 <输入> 标签,包括提交按钮。 当单击提交按钮时,表单中的项将发送到在 action 属性的属性中指定的URL。 <窗体> 然后,目标URL可以检查这些 <输入> 标记并执行所需操作。

但是,你可能会发现这样的Fragment在插入到 ASP.NET 页面时无法正常工作。 主要的问题是 ASP.NET 页面已经定义了一个表单。 为了使 ASP.NET's postback 机制正常工作,所有控件都放置在 <窗体> 标记由于HTML不允许嵌套 <窗体> 标记,如将 上面 显示为 ASP.NET 页面中的代码会导致问题。

有许多可能的方法来解决这个问题。 让我从一些我认为不理想的开始吧。 第一种方法是在结束后简单地移动插入的HTML代码 </窗体> ASP.NET 窗体的标记。 尽管你不能筑巢 <窗体> 标签,可以包含多个非嵌套 <窗体> 同一页上的标签。

这样做的结果是页面现在有两个单独 <窗体> 标签,你会发现这通常是正常工作的。 然而,这里的问题是你失去了一些 ASP.NET 功能。 例如,插入的HTML代码来自于你的ASP.NET 窗体,因这里它并不真正嵌入到 ASP.NET 内容中。 如果使用母版页,则不能在内容页中执行这里操作,因为内容页中的所有内容都位于页的内部。 <窗体> 母版页中定义的标记。

第二种方法是一种丑陋的hack,如下所示:

protectedvoid btnPayPal_Click(object sender, ImageClickEventArgs e)
{
 System.Web.HttpContext.Current.Response.Clear();
 System.Web.HttpContext.Current.Response.Write("<html><head>");
 System.Web.HttpContext.Current.Response.Write("</head><body" + 
 "onload='document.form1.submit()'>");
 System.Web.HttpContext.Current.Response.Write("<form" + 
 "action='https://www.paypal.com/cgi-bin/webscr'" +
 "name='form1' method='post'>");
 System.Web.HttpContext.Current.Response.Write("<input" + 
 "type='hidden' name='cmd' value='_xclick'>");
 System.Web.HttpContext.Current.Response.Write(
 "<input type='hidden' name='business'" +
 "value='bob@domain.com'>");
 System.Web.HttpContext.Current.Response.Write(
 "<input type='hidden' name='lc' value='US'>");
 System.Web.HttpContext.Current.Response.Write(
 "<input type='hidden' name='item_name' value='Widget'>");
 System.Web.HttpContext.Current.Response.Write(
 "<input type='hidden' name='amount' value='100.00'>");
 System.Web.HttpContext.Current.Response.Write(
 "<input type='hidden' name='currency_code' value='USD'>
 System.Web.HttpContext.Current.Response.Write(
"<input type='hidden' name='bn'" +
"value='PP-BuyNowBF:btn_buynow_LG.gif:NonHostedGuest'> System.Web.HttpContext.Current.Response.Write(
 "<input type='image'" +
 "src='https://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif'" +
 "border='0' name='submit' alt=''>");
 System.Web.HttpContext.Current.Response.Write("<img alt='' border='0'" +
 "src='https://www.paypal.com/en_US/i/scr/pixel.gif'" +
 "width='1' height='1'>");
 System.Web.HttpContext.Current.Response.Write("</form>");
 System.Web.HttpContext.Current.Response.Write("</body></html>");
 System.Web.HttpContext.Current.Response.End();
}
执行 non-ASP.NET postback的丑陋 hack

这里代码运行于用户单击名为 btnPayPal的按钮时。 它动态创建一个HTML页面,然后将它服务到用户的浏览器。 创建的页面在我们的第一个列表中复制了该表单,但在页面中添加了一个 onload 属性 <正文> 标记,使窗体在加载时立即提交,并且用户永远不会看到这里临时页。

这绝对是个丑陋的hack。 当它工作的时候它也有一些问题。 主要问题是,在运行代码后,用户在浏览器中按下后退按钮,这会导致同样的操作。

在探索这两个选项之后,我终于解决了第三种方法,看起来更直观并且没有任何主要问题。 按 ASP.NET 2.0开始,按钮有一个名为 PostBackUrl的属性,该属性可以用于将按钮回发到包含按钮的页面。

乍一看,这似乎没有什么帮助。 ASP.NET 按钮被设计回 ASP.NET 页面。 而且我想回 non-ASP.NET 页。 但是,postback 机制在两种情况下都是相同的。 如果我们回到 non-ASP.NET 页面,我们将向目标页面发送 ASP.NET 窗体上所有表单项的额外数据。 但是,只要它们没有冲突的项目名称,这是不可能的,这实际上不是问题。

拥有这些知识之后,我们可以重写原始代码 block 并将它的插入 ASP.NET 页面。

<inputtype="hidden"name="cmd"value="_xclick"><inputtype="hidden"name="business"value="bob@domain.com"><inputtype="hidden"name="lc"value="US"><inputtype="hidden"name="item_name"value="Widget"><inputtype="hidden"name="amount"value="100.00"><inputtype="hidden"name="currency_code"value="USD"><inputtype="hidden"name="bn"value="PP-BuyNowBF:btn_buynow_LG.gif:NonHostedGuest"><asp:ImageButtonID="ImageButton1"runat="server"ImageUrl="https://www.paypal.com/en_US/i/btn/btn_buynow_LG.gif"PostBackUrl="https://www.paypal.com/cgi-bin/webscr"/>
PayPal按钮插入 ASP.NET 页面

我已经删除了 <窗体> 从此代码中标记。我们不需要它,因为我们的ASP.NET 窗体已经定义了 <窗体> 标记我已经删除了 <> 并提交 <输入> 我已经用 ImageButton 替换了它们。 在原始代码中,我将属性 ImageButtonImageUrl 设置为相同的PayPal按钮图像,最后,我将 PostBackUrl 属性设置为属性指定的URL。 <窗体> 原始HTML代码中的标记。

结果是,当点击 ImageButton 时,整个表单被发布到 PayPal URL。 就像前面提到的,这包括所有其他 ASP.NET 值,包括页面数据的ViewState。 但是,ViewState是加密的,PayPal站点只会查看它感兴趣的那些值。

结果是,我可以在 ASP.NET 窗体中插入一个from按钮,我仍然能够使用所有的ASP.NET 特性。


IMP  asp  asp-net  pos  POST  Posts  
相关文章