|
Since publishing my Posting to an Posting to an Off-Site Page in DotNetNuke article, I've received many emails from visitors who appreciated the information and the AWeber form conversion tool. Interestingly, many of you have been able to use the conversion tool or the technique I described to solve similar problems with off-site services other than AWeber and with other environments than DotNetNuke.
It turns out that the source of the problem with posting to an off-site page has more to do with ASP.NET architecture than with any specific application framework or target vendor. The crux of the problem is that ASP.NET wraps every page inside one big form.
If you think about how ASP.NET works to provide a rich programming environment that isolates you from the idiosyncrasies of DHTML, JavaScript, and HTTP stateless request-driven programming, you can see why Microsoft made this architecture decision. Putting everything inside a form lets ASP.NET use an HTTP POST to send enormous quantities of information back to the server (ViewState, in particular). Couple that capability with a creative use of JavaScript, and you get the advanced features you now expect from ASP.NET server controls.
The AWeber problem came about because the code AWeber gives you is supposed to be pasted onto a standard HTML page. Their subscribe form is wrapped within its own form tag, and you can't put a form inside a form. That is why their code does not work as-is on any ASP.NET web page.
In spite of the wonder and glory that is ASP.NET, if you look under the hood, it's all smoke and mirrors. Don't get me wrong, I think ASP.NET is an amazing work of technology, but ultimately, it is just an application framework and code generator for other technology that has been in place for a long time.
If you do a view source on an ASP.NET web page, you can see a little bit of the man behind the curtain. Those of us who have been developing web sites since before ASP.NET came along see very little that is new. Even AJAX doesn't bring anything to the mix that hasn't been in place since the 90's: it is just a new framework for "old" technologies.
My solution for posting to AWeber from DNN came about when I did a view source on the DNN page that hosted my subscribe form. Here is the key bit of code you'll find at the top of every page ASP.NET generates:
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
This chunk of code is behind almost every postback that your page controls invoke. I say almost, because ASP.NET uses alternate functions, namely __doPostBackWithOptions, if your controls use certain features like the PostBackUrl property.
However, the __doPostBack function itself is not the key. It is the fact that ASP.NET conveniently exposes the form object through the "theForm" global variable that is important. That little bit of information is what makes it easy to post any ASP.NET page to any URL.
The DNN article describes a solution that effectively replaces the __doPostBack function, but the converter tool takes an even simpler approach. It hijacks the form post with script coded directly into an anchor tag:
<a href="javascript:
theForm.__VIEWSTATE.value='';
theForm.__dnnVariable='';
theForm.encoding='application/x-www-form-urlencoded';
theForm.action='http://www.aweber.com/scripts/addlead.pl';
theForm.submit();"
name="submit">Subscribe</a>
Note that I've introduced line breaks here for readability. Normally, everything within the quoted href attribute value would have to be on one line.
So what is happening here? The script you see in the href tag bypasses the normal page post logic and submits the form directly. Here's what it is doing:
- First it clears ViewState by emptying the __VIEWSTATE hidden field. The value is usually huge and no external site is going to need it.
- Next it clears the __dnnVariable hidden field, which is also junk to an external site. You only need to do this on a DNN site, of course.
- It then sets the form encoding back to the default encoding method. It does this because DNN sets the form encoding to multipart/form-data to allow for uploads. Again, you may not need this for other ASP.NET pages.
- Now for the critical part: It overrides the form action attribute with the target URL. This is where you are "hijacking" the form post.
- Finally, the script submits the form.
This technique is crazy simple and it allows you to embed any number of forms going to any URL on the web within any ASP.NET page.
Of course, there are security implications here too. This trick is one of the reasons why you must be careful to protect your pages against script injection. A nefarious user could stuff a form that posts to their site within your site using this technique.
Another thing to keep in mind is that you not only post the content of the controls in your embedded form, but you post the content of every other input control on the page. If your page has other controls that you want to hide from the target URL, you should clear them as I did with ViewState.
So now you know how the AWeber form converter does its magic, and you know how you can embed forms that post to external web sites in your ASP.NET pages. You also know a little bit more about ASP.NET's internal architecture.
This trick is easy to apply, once you know what to do. As simple as it is, I must admit the knowledge was hard-won. I spent a lot of time surfing the web for solutions and several hours playing with alternatives before having the "ah-ha" moment that led to this approach. Hopefully, I just saved you from having a similar experience.
Visitor Comments
To submit your comments, click the "Please click here to send feedback" link below. |
|