How to POST and Redirect from the server

T

tsides

I have been searching this site for hours, and I have not found the
answer I am looking for.

I would like to send users to PayPal from my ASP.NET site. However, I
do not want the users to be able to change the price they'll pay for
their items. This is not as easy as it seems.

The standard process is to create a static HTML page and HTML form,
and then HTTP POST the values to the proper page at Paypal. But users
can create their own copies of my HTML pages, modify the values of the
hidden form fields, and POST through with their own prices.

Therefore, I'd like to use an ASP.NET page instead. An item number
goes out on the HTML page, and it's associated price stays in memory
on the server. The form and "Buy" buttons are therefore
"runat=server". On clicking the Buy button, I'd like the price (and
other options) to be supplied by the server, and processing to pass
drectly to the Paypal without aything going back to the user for
tampering.

Options I think don't work:
1. use WebRequest
Y: retrieves the HTML source code for Paypal's page, but doesn't show
the page to the user! Maybe I'm doing something wrong? see my code
below....

2. Response.Rediret(paypal.com/page?price=x&item=...
Y: With query strings, prices are now in the address bar on the user's
browser; change the address, click Go, and users gets a new price.
Follow-up: encrypting the URL isn't much help either; too many
hex/octal/etc. decrypters out there

3. System.Transfer(paypal.com...
Y: only works on same-server transfers

4. System.Transfer(MyPostingPage.aspx?price=x... where the Page_Load
does the POST to paypal , gets the HTML result, assigns that HTML as
the only HTML for MyPostingPage.aspx, and displays it.
Y: Paypal's references to javascript files, style sheets, etc. are
relative, so displaying that HTML as a part of a web page on my server
breaks the page.
Implementation clarification: HTML for MyPostingPage.aspx is simply
the non-.NET ASP syntax: <%=PageContent%>. The code behind has
PageContent as a global public variable, and the Page_Load function
ends with:
ReceiveStream = result.GetResponseStream()
sr = New StreamReader(ReceiveStream, encode)
PageContent = sr.ReadToEnd()

5. use javascript. After post-back, add the price fields to the HTML
of the page, change the form's attributes to post to PayPal instead of
itself, and add a javascript which will automatically POST the form
once the page arrives at the browser.
Y: users can disable javascript, and then they'll have access to the
HTML page and all it's hidden fields and values.

6. Modify receiving page in some way
Y: obviously, receiving pages are PayPal's, not mine

7. Implement a manual review process and deny purchases where prices
have been changed.
Y: a successful purchase will grant immediate access to a web site;
users will not be waiting days for me to review purchases....


SO CAN ANYONE TELL ME HOW TO POST and REDIRECT FROM THE CODE-BEHIND?

Or have I just screwed something up in my WebRequest code? I've
looked at the request stream, and, sure enough, it contains the entire
PayPal page! BUt why won't it redirect me to it, like it would have
if I was posting from an HTML page?

Dim req As System.Net.WebRequest

req = System.Net.WebRequest.Create("https://www.paypal.com/cgi-bin/webscr")
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"

Dim UrlEncoded As New StringBuilder
UrlEncoded.Append("cmd=_xclick")
UrlEncoded.Append("&[email protected]")
UrlEncoded.Append("&item_name=Item1")
UrlEncoded.Append("&amount=100.00")
UrlEncoded.Append("&currency_code=USD")
UrlEncoded.Append("&no_shipping=1")
UrlEncoded.Append("&return=http://myserver.com/mypage.aspx")
UrlEncoded.Append("&cancel_return=http://myserver.com/mycancelpage.aspx")

Dim SomeBytes() As Byte
SomeBytes = System.Text.Encoding.UTF8.GetBytes(UrlEncoded.ToString())

req.ContentLength = SomeBytes.Length

Dim RequestStream As Stream
RequestStream = req.GetRequestStream()
RequestStream.Write(SomeBytes, 0, SomeBytes.Length)
RequestStream.Close()

Dim result As WebResponse
result = req.GetResponse

Dim ReceiveStream As Stream
ReceiveStream = result.GetResponseStream()

Dim encode As Encoding
encode = System.Text.Encoding.GetEncoding("utf-8")

Dim sr As StreamReader
sr = New StreamReader(ReceiveStream, encode)

result.Close()

Thank you!
 
K

Kevin Spencer

Using a WebRequest is the right idea. However, you're not returning the
Response Stream from the PayPal server to the browser in the Page's
Response. The basic flow of your code should go like this:

Receive Request from your Page via PostBack
Create a WebRequest to PayPal using POST
Get the Response Stream back from the WebRequest
Return the Response Stream from the WebRequest to your Page's Response

--
HTH,
Kevin Spencer
..Net Developer
Microsoft MVP
Big things are made up
of lots of little things.
 
T

Trevor Sides

Can you give me the specific code I should use to to "return the
Response Stream to the browser"? I thought I had tried what you
describe in scenario #4, without any luck because the HTML that I get
from PayPal has relative links in it which won't resolve. Let me be
more specific on the code I was using:

Poster.aspx:
<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="Poster.aspx.vb" Inherits="Test.Poster"%>
<%=PageContent%>

Poster.aspx.vb:
Imports System.IO 'for Stream type
Imports System.Net 'for WebResponse type
Imports System.Text 'for the StringBuilder type

Public Class Poster
Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

Public PageContent As String

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Response.RedirectLocation =
"https://www.paypal.com/cgi-bin/webscr"

Dim req As System.Net.WebRequest

req =
System.Net.WebRequest.Create("https://www.paypal.com/cgi-bin/webscr")
req.Method = "POST"
req.ContentType = "application/x-www-form-urlencoded"

Dim UrlEncoded As New StringBuilder
UrlEncoded.Append("cmd=_xclick")
UrlEncoded.Append("&[email protected]")
UrlEncoded.Append("&item_name=Item1")
UrlEncoded.Append("&amount=100.00")
UrlEncoded.Append("&currency_code=USD")
UrlEncoded.Append("&no_shipping=1")
UrlEncoded.Append("&return=http://myurl")
UrlEncoded.Append("&cancel_return=myurl")

Dim SomeBytes() As Byte
SomeBytes =
System.Text.Encoding.UTF8.GetBytes(UrlEncoded.ToString())

req.ContentLength = SomeBytes.Length

Dim RequestStream As Stream
RequestStream = req.GetRequestStream()
RequestStream.Write(SomeBytes, 0, SomeBytes.Length)
RequestStream.Close()

Dim result As WebResponse
result = req.GetResponse

Dim ReceiveStream As Stream
ReceiveStream = result.GetResponseStream()

Dim encode As Encoding
encode = System.Text.Encoding.GetEncoding("utf-8")

Dim sr As StreamReader
sr = New StreamReader(ReceiveStream, encode)

PageContent = sr.ReadToEnd()

result.Close()
End Sub
End Class
 
K

Kevin Spencer

The links may be relative, but they are relative to the domain of the server
from which they came. Therefore, and this will require some work, but you
may have to massage the HTML returned from the remote server, by appending
the domain portion of the URls in the returned document, prior to returning
it to the client. An alternative would be to not return the actual page from
the remote server, but to parse it and return your own results page to the
client.

--
HTH,
Kevin Spencer
..Net Developer
Microsoft MVP
Big things are made up
of lots of little things.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top