【问题标题】:Response.Write with an iframeResponse.Write 使用 iframe
【发布时间】:2013-05-09 02:13:18
【问题描述】:

我继承了一个使用 Cyber​​source 作为信用卡处理公司的应用程序。它目前使用 Cyber​​Source API,我正在尝试将其转换为使用他们托管的订单页面 - 特别是静默订单发布方法。 Cyber​​Source 给出的运行示例如下:

<form action="https://orderpagetest.ic3.com/hop/ProcessOrder.do" method="POST">
    <% insertSignature3("10", "USD", "sale"); %>
        <h2>Payment Information</h2>
        Card Type:      <select name="card_cardType"><br>
                            <option value="">
                            <option value="001">Visa
                            <option value="002">MasterCard
                            <option value="003">American Express
                        </select><br>
        Card Number:        <input type="text" name="card_accountNumber"><br>
        Expiration Month:   <input type="text" name="card_expirationMonth"> (mm)<br>
        Expiration Year:    <input type="text" name="card_expirationYear"> (yyyy)<br><br>

    <h2>Ready to Check Out!</h2>
                            <input type="submit" name="submit" value="Buy Now">

</form>

insertSignature 方法的代码如下:

 public void insertSignature3( String amount, String currency, String orderPage_transactionType )
    {
        try
        {
            TimeSpan timeSpanTime = DateTime.UtcNow - new DateTime( 1970, 1, 1 );
            String[] arrayTime = timeSpanTime.TotalMilliseconds.ToString().Split( '.' );
            String time = arrayTime[0];
            String merchantID = GetMerchantID();
            if ( merchantID.Equals( "" ) )
                Response.Write( "<b>Error:</b> <br>The current security script (HOP.cs) doesn't contain your merchant information. Please login to the <a href='https://ebc.cybersource.com/ebc/hop/HOPSecurityLoad.do'>CyberSource Business Center</a> and generate one before proceeding further. Be sure to replace the existing HOP.cs with the newly generated HOP.cs.<br><br>" );
            String data = merchantID + amount + currency + time + orderPage_transactionType;
            String pub = GetSharedSecret();
            String serialNumber = GetSerialNumber();
            byte[] byteData = System.Text.Encoding.UTF8.GetBytes( data );
            byte[] byteKey = System.Text.Encoding.UTF8.GetBytes( pub );
            HMACSHA1 hmac = new HMACSHA1( byteKey );
            String publicDigest = Convert.ToBase64String( hmac.ComputeHash( byteData ) );
            publicDigest = publicDigest.Replace( "\n", "" );
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append( "<input type=\"hidden\" name=\"amount\" value=\"" );
            sb.Append( amount );
            sb.Append( "\">\n<input type=\"hidden\" name=\"currency\" value=\"" );
            sb.Append( currency );
            sb.Append( "\">\n<input type=\"hidden\" name=\"orderPage_timestamp\" value=\"" );
            sb.Append( time );
            sb.Append( "\">\n<input type=\"hidden\" name=\"merchantID\" value=\"" );
            sb.Append( merchantID );
            sb.Append( "\">\n<input type=\"hidden\" name=\"orderPage_transactionType\" value=\"" );
            sb.Append( orderPage_transactionType );
            sb.Append( "\">\n<input type=\"hidden\" name=\"orderPage_signaturePublic\" value=\"" );
            sb.Append( publicDigest );
            sb.Append( "\">\n<input type=\"hidden\" name=\"orderPage_version\" value=\"4\">\n" );
            sb.Append( "<input type=\"hidden\" name=\"orderPage_serialNumber\" value=\"" );
            sb.Append( serialNumber );
            sb.Append( "\">\n" );
            Response.Write( sb.ToString() );
        }
        catch ( Exception e )
        {
            Response.Write( e.StackTrace.ToString() );
        }
    }

当我在测试应用程序中运行它时,一切正常。但是,我不能在我的主应用程序中使用表单标签,因为主页面的所有内容都包含在表单标签中,这将导致嵌套的表单标签。我尝试将表单块放入 iframe,但无法弄清楚如何通过 insertSignature(...) 方法的 Response.Write 调用传递附加信息。

欢迎提出任何建议。

【问题讨论】:

    标签: html asp.net forms iframe


    【解决方案1】:

    我刚刚遇到了同样的问题。我们还采用了 iframe 方法。在页面加载时(如果是回发),您需要在请求中写出特定项目(不包括 ViewState)。下面的示例显示了写出所有项目(ViewState 除外)。它被包裹在一个 ccInfo span 中,然后我们可以通过 JavaScript 获取它。

    protected virtual void Page_Load(Object sender, EventArgs e)
    {
    
        if (!Page.IsPostBack)
        {
            //Do any page binding, etc that needs to be done on intitial page load
        }
        else
        {
            //We came back from CyberSource ...
    
            //Will need to get from stored client hidden field ...
            string decision = Request.Form["decision"];
    
            if (verifyTransactionSignature(Request))
            {
                //Make sure we are only processing in the TEST environment if the particular setting
                //is set to test (Site_Settings.CYBERSOURCE_API_URL contains 'test' in it)
                string apiUrl = Settings.GetSetting(LocalConnectionString, "CYBERSOURCE_API_URL");
                //API isn't test, but CyberSource is (someone hacking?)
                if (!apiUrl.ToLower().Contains("test") && Request.Form["orderPage_environment"].ToLower().Contains("test"))
                {
                    lblError.Text = "Unable to verify credit card. Request is in test mode, but the site is not.  Contact Customer Service.";
                }
    
                Response.Write("<span class='ccInfo hide'>");
                for (int i = 0; i < Request.Form.Count; i++)
                {
                    var key = Request.Form.GetKey(i);
    
                    if (key != "__VIEWSTATE")
                    {
                        Response.Write("<input type='hidden' id='" + key + "' name='" + key + "' value='" + Request.Form[i] + "' class='hide' />");
                    }
                }
                Response.Write("</span>");
    
                if (decision != "ACCEPT")
                {
                    string reasonCode = Request.Form["reasonCode"];
    
                    lblError.Text = "Unable to verify credit card (" + reasonCode + ") ";
                    if (reasonCode == "102")
                    {
                        lblError.Text += "<br />One or more fields in the request contains invalid data.  Typically this is the expiration date";
                    }
                }
            }
            else
            {
                lblError.Text = "Unable to verify credit card. Transaction Signature not valid.  Contact Customer Service.";
            }
        }
    }
    

    我们用来获取该数据然后发送到父页面的 JavaScript 如下:

    $(document).ready(function () {
        var decision = $('#decision');
    
        if (decision.length > 0) {
            if (decision.val() === "ACCEPT") {
                //pass in requestId, etc to the billing page
                parent.$('.checkoutform').append($('.ccInfo').children());
    
                //call billing.aspx submit function
                parent.submitBillingPage();
    
                return;
            } else {
                //change from loading animation to iframe
                parent.toggleIframe(true);
            }
        }
    });
    

    父页面具有“checkoutform”类名,因此我们可以将 ccInfo span 的所有元素附加到 iframe 中。这一行将我们使用服务器端代码编写的所有元素推送到父页面。现在,父页面包含了从 Cyber​​Source 返回的所有信息。

    我们的账单页面(父页面)允许除了 Cyber​​Source 信用卡之外的其他付款,所以我们基本上在主页上进行提交,假设一切都从 Cyber​​Source 成功返回。当用户未使用 Cyber​​Source 付款时,我们会在计费页面上显示主提交按钮。如果是,我们隐藏主提交按钮,并显示 iframe 中的提交按钮。然后,如果出现问题,我们要么在 iframe 中显示错误消息,要么在将数据从 iframe 传输到父页面后在父页面上提交表单。

    最后,通过查看 Request.Form,父页面可以通过服务器端代码访问所有数据。

    希望这有助于或至少让您朝着正确的方向前进。我知道这个问题已经有一个多月了,你可能已经继续前进了,但也许它会帮助其他人。

    【讨论】:

      猜你喜欢
      • 2015-02-06
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多