Posta form-data till en extern URL

Jag kommer ihåg när man jobbade med klassisk ASP, och gick över till ASP.NET, att begreppet PostBack var rätt förvirrande. Typ: "Vadå ska varje sida posta tillbaks till sig själv?" Efter ett tag förstod man finessen och nu skulle skulle jag inte vilja byta tillbaks till hur föregångaren fungerade.

Ibland vill man dock kunna posta data från ett formulär till en annan URL, speciellt när man har att göra med betalväxlar (t ex Postens betalväxel), som ofta fungerar så.

PostBackUrl

I ASP.NET 1.1 var det rätt begränsade möjligheter men i 2.0 fick vi attributet PostBackUrl som kan sättas på Button, LinkButton och ImageButton. Har aldrig använt det själv men borde fungera bra.

HttpWebRequest

Med HttpWebRequest kan man skicka webbströmmar med data. Passar bäst om man vill att postningen ska ske i bakgrunden om jag förstått det rätt, och inte lika bra om man vill att webbläsaren ska följa URLen, som postningen sker till. Jag kan ha fel här för har inte provat så mycket med denna metod. Här är ett exempel som verkar rätt lätt att förstå.

Med JavaScript

Man kan lägga till ett extra formulär på sidan och posta detta genom att registrera ett javascript, från koden bakom, ungefär så här.

string sendScript = "<script language='javascript'>document.getElementById('paymentform').submit();<"+"/script>";
Page.RegisterStartupScript("SendPayment", sendScript);

På det extra formuläret anger man den externa URLen i action och variablerna som hidden-inputs.

<form id="paymentform" name="paymentform" action="https://thepaymentservice.domain" method="post">
<input type="hidden" id="Card_num" runat="server">
<input type="hidden" id="Currency" runat="server">
<input type="hidden" id="Amount" runat="server">
</form>

Eller så bygger man formuläret själv

Här är ett exempel på hur man kan använda HttpContext för att helt enkelt bygga ihop formuläret själv med html-taggar. Det är skrivet av Jigar Desai och finns att ladda hem på C# Corner.

Här kommer lätt modifierad variant:

using System;
using System.Web;
using System.Text;
using System.Collections.Specialized;

/// <summary>
/// Summary description for RemotePost
/// </summary>

public class RemotePost
{
private NameValueCollection inputs = new NameValueCollection();

private string url = string.Empty;
public string Url
{
set{ url = value; }
}
private string method = "post";
private string formName = "form1";

public void Add(string name, string value)
{
inputs.Add(name, value);
}

public void Post()
{
HttpContext.Current.Response.Clear();

StringBuilder sb = new StringBuilder();

sb.Append("<html><head>");

sb.Append(string.Format("</head><body onload=\"document.{0}.submit()\">", formName));
sb.Append(string.Format("<form name=\"{0}\" method=\"{1}\" action=\"{2}\" >", formName, method, url));

for (int i = 0; i < inputs.Keys.Count; i++)
{
sb.Append(string.Format("<input name=\"{0}\" type=\"hidden\" value=\"{1}\">", inputs.Keys[i], inputs[inputs.Keys[i]]));
}

sb.Append("</form>");
sb.Append("</body></html>");

HttpContext.Current.Response.Write(sb.ToString());

HttpContext.Current.Response.End();
}
}

Man anropar klassen så här:

RemotePost remotePost = new RemotePost();
remotePost.Url = "http://theRemoteDomain/Page.aspx";
remotePost.Add("field1","This is my first value");
remotePost.Add("field2","And another one");
remotePost.Post();

Comments

Sweet.. Fungerar som en klocka! Har försökt göra detta själv nån gång men fungerade inte riktigt som det skulle vid tillfället.