开发者

MVC HtmlHelpers trouble with Razor

I'm working on a non-profit donation platform and I'm using MVC for the first time. I've got the hang of it for the most part but right now I'm having a problem that I dont know how to address. I'm using the AthorizeNet.Helpers class and when I add the code from the expamples, it works for the most part except for it takes the form and puts it ABOVE the tag however it puts the form fields in the correct place. I'm trying to figure out how to render the tag in the correct place.

@using AuthorizeNet.Helpers;

@using (Html.BeginSIMForm("http://127.0.0.1:4768", 1.99M, "xxx_key", "yyy_key", true))
{
    @Html.Raw(Html.CheckoutFormInputs(true))
    @Html.Hidden("order_id", "1234")
    <input type = "submit" value = "Pay" />
}

This is how it looks in HTML output:

<form action = 'https://test.authorize.net/gateway/transact.dll' method = 'post'>
    <input type = 开发者_运维知识库'hidden' name = 'x_fp_hash' value = '6bef386eaa89944efd62b47b86042910' \>
    <input type = 'hidden' name = 'x_fp_sequence' value = '117'\>
    <input type = 'hidden' name = 'x_fp_timestamp' value = 'xxx_key' \>
    <input type = 'hidden' name = 'x_login' value = 'yyy_key' \>
    <input type = 'hidden' name = 'x_amount' value = '1.99' \>
    <input type = 'hidden' name = 'x_relay_url' value = 'http://127.0.0.1:4768' \>
    <input type = 'hidden' name = 'x_relay_response' value = 'TRUE' \>
</form><!DOCTYPE html>
<html>
<body>
<h2>Payment Information</h2>
                <div style = 'border: 1px solid #990000; padding:12px; margin-bottom:24px; background-color:#ffffcc;width:300px'>Test Mode</div>
                <div style = 'float:left;width:250px;'>
                    <label>Credit Card Number</label>
                    <div id = 'CreditCardNumber'>
                        <input type = 'text' size = '28' name = 'x_card_num' value = '4111111111111111' id = 'x_card_num'/>
                    </div>
                </div>  
                <div style = 'float:left;width:70px;'>
                    <label>Exp.</label>
                    <div id = 'CreditCardExpiration'>
                        <input type = 'text' size = '5' maxlength = '5' name = 'x_exp_date' value = '0116' id = 'x_exp_date'/>
                    </div>
                </div>
                <div style = 'float:left;width:70px;'>
                    <label>CCV</label>
                    <div id = 'CCV'>
                        <input type = 'text' size = '5' maxlength = '5' name = 'x_card_code' id = 'x_card_code' value = '123' />
                    </div>
                </div><input id="order_id" name="order_id" type="hidden" value="1234" />        <input type = "submit" value = "Pay" />


This is how I fixed it.

As you stated, add @Html.Raw() around Html.CheckoutFormInputs(true)

The other change to make is in

namespace AuthorizeNet.Helpers -> CheckoutFormBuilders.cs

add a using of

using System.IO;

Change

HttpResponseBase to TextWriter

I did this in three spots.

HttpResponseBase _response; to TextWriter _response;

public SIMForm(TextWriter response, string returnUrl, decimal amount, 
               string apiLogin, string transactionKey)
               :this(response,returnUrl,amount,apiLogin,transactionKey,true){}

public SIMForm(TextWriter response, string returnUrl, decimal amount, 
               string apiLogin, string transactionKey, bool isTest) {
        _response = response;
        _amount = amount;
        _apiLogin = apiLogin;
        _transactionkey = transactionKey;
        _returnUrl = returnUrl;
        _isTest = isTest;
        OpenForm();
}

Two more changes left

As directed in tpeczek answer, you need to change

helper.ViewContext.HttpContext.Response 

to

helper.ViewContext.Writer

This will look like

public static SIMForm BeginSIMForm(this HtmlHelper helper, string returnUrl, 
                                decimal amount, string apiLogin, 
                                string transactionKey) {

return new SIMForm(helper.ViewContext.Writer,
                    returnUrl,amount,apiLogin,
                    transactionKey,true);}

public static SIMForm BeginSIMForm(this HtmlHelper helper, string returnUrl, 
                                decimal amount, string apiLogin, 
                                string transactionKey, bool isTest) {

return new SIMForm(helper.ViewContext.Writer, 
                    returnUrl, amount, apiLogin, 
                    transactionKey,isTest);}


This kind of problem usually happens when a helper which is writing directly to output stream was written for ASP.NET MVC 1 (and helpers that are enclosed in using are writing directly to output stream most of the time). In ASP.NET MVC 1 you could write to output stream by using this:

htmlHelper.ViewContext.HttpContext.Response.Output

In later ASP.NET MVC version you should be using this:

htmlHelper.ViewContext.Writer

That ensures Razor compatibility. If you have access to AuthorizeNet.Helpers source code you can fix it by yourself, if you don't than you have to contact authors for fixing it.


It's possible that the helper from AuthorizeNet is not written correctly to work with Razor. Without actually looking at the source of their assembly it's hard to say if that's the case. You might want to try to get in touch with their customer support.


Using the example from EpicThreeDev above I was able to get the form html to appear correctly. The Pay button however, was juxtaposed above the ccv field, so in order to fix that on the Index.cshtml code base I changed the HTML to

                     <br />                           
     <input type = "submit" value = "Pay"  style="position:relative; top:35px;" />    

once I did that I was able to post the form, however after doing that I got the error that is addressed in post.

http://community.developer.authorize.net/t5/Integration-and-Testing/Having-Trouble-setting-up-MVC3-application-with-DPM/m-p/13226


Here's my solution. It just prints the Authorize.net hidden fields, so you can write your own form tag. Fill in your web.config with the relevant AppSettings values. This way you can easily change between development and production.

 public static class MyAuthNetHelper
 {
    public const string TEST_URL =  "https://test.authorize.net/gateway/transact.dll";
    public const string LIVE_URL = "https://secure.authorize.net/gateway/transact.dll";

    public static string ApiLogin
    {
        get { return ConfigurationManager.AppSettings["AuthNetAPILogin"]; }
    }

    public static string TransactionKey
    {
        get { return ConfigurationManager.AppSettings["AuthNetAPITransactionKey"]; }
    }

    public static string ReturnUrl
    {
        get { return ConfigurationManager.AppSettings["AuthNetReturnUrl"]; }
    }

    public static string ThanksUrl
    {
        get { return ConfigurationManager.AppSettings["AuthNetThanksUrl"]; }
    }

    public static bool TestMode
    {
        get { return bool.Parse(ConfigurationManager.AppSettings["AuthNetTestMode"]); }
    }

    public static string GatewayUrl
    {
        get { return TestMode ? TEST_URL : LIVE_URL; }
    }

    public static MvcHtmlString AuthNetDirectPostFields(this HtmlHelper helper, decimal amount)
    {

        var seq = Crypto.GenerateSequence();
        var stamp = Crypto.GenerateTimestamp();

        var fingerPrint = Crypto.GenerateFingerprint(TransactionKey,
            ApiLogin, amount, seq.ToString(), stamp.ToString());

        var str = new StringBuilder();

        str.Append(helper.Hidden("x_fp_hash", fingerPrint));
        str.Append(helper.Hidden("x_fp_sequence", seq));
        str.Append(helper.Hidden("x_fp_timestamp", stamp));
        str.Append(helper.Hidden("x_login", ApiLogin));
        str.Append(helper.Hidden("x_amount", amount));
        str.Append(helper.Hidden("x_relay_url", ReturnUrl));
        str.Append(helper.Hidden("x_relay_response", "TRUE"));

        return MvcHtmlString.Create(str.ToString());
    }   
}

cshtml:

    <form id="paymentForm" method="POST" action="@MyAuthNetHelper.GatewayUrl" class="form-horizontal offset1">
@Html.AuthNetDirectPostFields(PutYourAmountHere)
...
</form>

ThanksUrl is used in your action to handle the response from Authorize.net. Check this for more: http://developer.authorize.net/integration/fifteenminutes/csharp/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜