I recently posted a solution to the eternal PayPal / ASP.NET form submission problem using Jeremy Schneider's custom GhostForm class. Since then, several people have made mention of a problem that I came across myself when coding this, namely getting your project to recognize the reference to the new custom form class.

PayPal Checkout Button

 

Using a Web Application Project in VS 2005, I recently came up against something similar when attempting to place the SqlHelper.cs class in the App_Code folder. At that time I offered a quick hack. Since then, I have thought better of using the App_Code folder in my Web Application Projects and just create a normal folder and put the helper class in there along with my data access class. The App-Code is more trouble than it is worth for a small project where there is practically zero compilation time to be saved anyway.

Back to the problem at hand... when attempting to compile, you may get the following error:

"The name 'mainForm' does not exist in the current context"

First, check your scopes; make sure that wherever you are using the mainForm object is in the same scope as the instantiation. Ideally, create a separate Class Library Project in your solution and add the custom form class to it. Compile your new project separately and reference that from your e-commerce project. Right-click the References folder in Solution Explorer and browse to the DLL for the custom form.

CustomForm Class Library Project

 

Add the following to your master page and ignore any red squigglies you get in Visual Studio:

<%@ Register TagPrefix="CF" Namespace="CustomForm" Assembly="CustomForm" %>
<body>
    <CF:GhostForm id="mainForm" runat="server">
    ...
</body>

 

Add markup to the ASPX for the dummy PayPal button and a functioning ASP.NET button:

<img src="https://www.sandbox.paypal.com/en_US/i/btn/btn_xpressCheckout.gif"> <asp:Button ID="checkoutBtn" runat="server" OnClick="CheckButton_Click"
    Text="Checkout" Width="100" CausesValidation="false" /> 

 

using CustomForm;

namespace MyProject
{
    public partial class purchase : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ...
            // Workaround for PayPal form problem
            GhostForm mainForm = new GhostForm();
            mainForm.RenderFormTag = false;
        }
        ...
    }
    ...
}

 

Although specific to my own project requirements, here's the complete handler code for the button click: 

        protected void CheckButton_Click(object sender, EventArgs e)
        {
            // Live PayPal URL
            // const string SERVER_URL = "https://www.paypal.com/cgi-bin/webscr";
            // Sandbox PayPal URL
            const string SERVER_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr";
           
            // Live business parameter
            // const string BUSINESS = "grace@graceguitars.com";
            // Sandbox business parameter
            const string BUSINESS = "tester@hotmail.com";

            // Return URL for IPN processing
            const string NOTIFY_URL = "http://www.mysite.com/PayPalReturnURL.aspx";

            decimal totalAmount = 0.00M;
            int productID = 0;
            int totalUnits = 0;
            decimal totalShipping = 0.00M;
            string paypalURL = "";
            string itemName = "Grace\'s Guitars";
            string itemNumber = "";

            if (cart.Count > 0)
            {
                BizClass biz = new BizClass();
              
                // TransactionID will be later used to check against IPN info
                string transID = Guid.NewGuid().ToString();
               
                // Create a new Order in DB
                orderID = biz.AddOrder(out orderID, transID, false, DateTime.Now);
                itemNumber = Convert.ToString(orderID);

                foreach (ShoppingCartItem item in cart)
                {
                    totalAmount += item.Total;
                    totalUnits += item.Units;
                    productID += item.ProductID;

                    // Store order details in database
                    biz.AddOrderDetails(orderID, productID, item.Units);
                }   
                // Eventually, use a SQL Server job to remove unconfirmed orders

                // Calculate total shipping cost for total number of units
                totalShipping = CalculateShipping(totalUnits);

                // Get back the URL-encoded URL for PayPal   
                paypalURL = GetPayPalURL(SERVER_URL, BUSINESS, itemName, itemNumber,
                    totalAmount, totalShipping, NOTIFY_URL);
                Response.Redirect(paypalURL, true);
            }
        }

 

You need to sign into your PayPal Developer account before submitting your test purchases. You will be able to see a history of your test transactions in the sandbox admin section.

PayPal Sandbox

 

If you want some sample code for constructing the URL, I suggest you check out the following whitepaper from Rick Strahl. This should be enough to see you up and running. Many times, people get compiler errors due to badly-formed namespace declarations and class references. Always double-check your code :-)

kick it on DotNetKicks.com   PHP, ASP, .NET, JSP Resources, Reviews

GhostForm.zip (448.00 bytes)




Seedling Up until today, CodersBarn was based on BlogEngine 1.1. using XML. I was having ongoing problems with the comments system, and honestly believe that without feedback from readers, nobody gains. So, for the past week, I have been working on porting it to the new 1.3 version using SQL Server. 

The comments system is now up and running :-) Please feel free to comment on any existing posts or to make suggestions on what content you would like to see from an ASP.NET point of view. Use the contact form to ask questions or to request code snippets. I will attempt to respond to all emails. Over time, the goal for this blog is to move closer to a real community, a community that shares the knowledge rather than guarding it like some trade secret known only to the few.

The CodersBarn blog only began last summer and is already receiving over 5,000 page views per month, roughly 2,300 unique hits. It takes a little time to find a niche that needs to be filled. In the future, I see this blog offering up more and more practical, "How To" articles and code samples. It's not a news blog and doesn't attempt to create traffic by throwing up cheap links to other people's work. The original idea was to create a place for students of software and professionals alike, to speak candidly about this great profession and where it's heading.

Hats off to Mads Kristensen and his colleagues who put BlogEngine.Net together. It's an amazing piece of blogging software and was sorely needed. Prior to the launch of this free blog engine I was already procrastinating for over a year on coding my own engine... a case of the mechanic's car? The availability of this software and the ease of installation saw this blog designed, a name chosen and registered, and the first post published, all in a single weekend. This migration to a databased version was made particularly easier by the availability of intructional installation videos from Al Nyveldt.




Mind Games Add this to your Christmas list! Neuro-engineering company Emotiv Systems have developed a headset that will allow you to control your electronic games using your thoughts alone. It's expected to market for around $299 next Christmas.

According to company president Tan Le, Emotiv's software algorithm "unfolds the cortex and takes us closer to the source of the signal." According to their website company overview: "while Emotiv Systems is currently focusing on the electronic gaming industry, the applications for the Emotiv technology and interface span an amazing variety of potential industries -- interactive television, accessibility design, market research, medicine, even security -- and plans for introducing Emotiv into these realms and more are already in the works".

All I can say is that if this communication channel is fully duplex, do not buy one for the wife!

Check the full story on Discovery.