How to send a POST in .net vb? - asp.net

What i am trying to do is get my user to enter in a phone number and message and then post it to text marketer which send the message.
at the moment if i use a response.redirect the message sense..
response.redirect("http://www.textmarketer.biz/gateway/?username=*****&password=*****&message=test+message&orig=test&number=447712345678")
However, i do not want to send the user there. all i want to do it post the data to the url and that's all for now and the user stay on the current page.
Any help?

actually, you don't have to do this server side (vb), just plain html will do the trick:
<html>
<body>
<form action="http://google.com" method="post">
<input type="hidden" value="somevalue"/>
<input Type="submit" value="Submit"/>
</form>
</body>
</html>
this will post the data (and in effect, redirect) to google.com.
Maybe you could use client script (jQuery) - $.ajax() or $.post(). but I think you will face cross domain restrictions (there is a workaround but its not that clean and straightforward).
Another is using the HttpWebRequest class. This is server side and the post will originate from your server instead of the client (as what the 1st approach will do). upon calling request.GetResponse(), you can retrieve the output from the remote server and render it on your page. But if you want to post and redirect to the remote url then I guess you should use the first approach.
EDIT:
try this in VB:
Option Infer On
Imports System.Net
Imports System.Text
Public Class Test
Private Sub TESTRUN()
Dim s As HttpWebRequest
Dim enc As UTF8Encoding
Dim postdata As String
Dim postdatabytes As Byte()
s = HttpWebRequest.Create("http://www.textmarketer.biz/gateway/")
enc = New System.Text.UTF8Encoding()
postdata = "username=*****&password=*****&message=test+message&orig=test&number=447712345678"
postdatabytes = enc.GetBytes(postdata)
s.Method = "POST"
s.ContentType = "application/x-www-form-urlencoded"
s.ContentLength = postdatabytes.Length
Using stream = s.GetRequestStream()
stream.Write(postdatabytes, 0, postdatabytes.Length)
End Using
Dim result = s.GetResponse()
End Sub
End Class
update2:
a GET request using HttpWebRequest in VB.net.
Dim s As HttpWebRequest
Dim username = "username=" + HttpUtility.UrlEncode("yourusername")
Dim password = "password=" + HttpUtility.UrlEncode("yourp#assword)!==&#(*#)!##(_")
Dim message = "message=" + HttpUtility.UrlEncode("yourmessage")
Dim orig = "orig=" + HttpUtility.UrlEncode("dunno what this is")
Dim num = "number=" + HttpUtility.UrlEncode("123456")
Dim sep = "&"
Dim sb As New StringBuilder()
sb.Append(username).Append(sep).Append(password).Append(sep)
sb.Append(message).Append(sep).Append(orig).Append(sep).Append(num)
s = HttpWebRequest.Create("http://www.textmarketer.biz/gateway/?" + sb.ToString())
s.Method = "GET"
Dim result = s.GetResponse()

you have to use the webrequest class. refer http://msdn.microsoft.com/en-us/library/debx8sh9.aspx

Don't do this server side, but client side using AJAX.
The jQuery ajax library is quite good.

Related

New Google Recaptcha with ASP.Net

I am attempting to get the new Google reCaptcha working in my ASP.NET project and I am having problems getting it to be the new one "I'm not a robot".
I had the old one in there and after doing much research on the developers.google.com web site, everything looks the same (they even point me to a download of the same dll - 1.0.5). So, I got the new keys and put them in and it works but it looks just like the old reCaptcha.
Has anyone gotten the new one to work with their ASP.Net? What am I missing?
EDIT:
So playing around in a test app and searching some other web sites I found that if I create a page like this:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>reCAPTCHA demo: Simple page</title>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form id="form1" runat="server" action="?" method="POST">
<div>
<div class="g-recaptcha" data-sitekey="My Public Key"></div>
<br/>
<asp:Button ID="Button1" runat="server" Text="Submit" />
</div>
</form>
</body>
</html>
And then in my code-behind (Button1_Click), I do this:
Dim Success As Boolean
Dim recaptchaResponse As String = request.Form("g-recaptcha-response")
If Not String.IsNullOrEmpty(recaptchaResponse) Then
Success = True
Else
Success = False
End If
The recaptchaResponse will either be empty or filled in depending on if they are a bot or not. The issue is, I now need to take this response and send it to google with my private key so I can verify that the response was not provided by a bot, in my code-behind, but I cannot figure out how. I tried this (in place of Success = True):
Dim client As New System.Net.Http.HttpClient()
client.BaseAddress = New Uri("https://www.google.com/recaptcha/")
client.DefaultRequestHeaders.Accept.Clear()
client.DefaultRequestHeaders.Accept.Add(New Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"))
Dim response As Net.Http.HttpResponseMessage = Await client.GetAsync("api/siteverify?secret=My Private key&response=" + recaptchaResponse)
If (response.IsSuccessStatusCode) Then
Dim CaptchResponse As ReCaptchaModel = Await response.Content.ReadAsAsync(Of ReCaptchaModel)()
Success = CaptchResponse.success
Else
Success = False
End If
But, I could not figure out how to get the async stuff working and I cannot find anything on what ReCaptchaModel is, so I found another way to call a web service and get a json response and tried this instead:
Dim request As Net.WebRequest = Net.WebRequest.Create("https://www.google.com/recaptcha/")
Dim Data As String = "api/siteverify?secret=My Private Key&response=" + recaptchaResponse
request.Method = "POST"
request.ContentType = "application/json; charset=utf-8"
Dim postData As String = "{""data"":""" + Data + """}"
'get a reference to the request-stream, and write the postData to it
Using s As IO.Stream = request.GetRequestStream()
Using sw As New IO.StreamWriter(s)
sw.Write(postData)
End Using
End Using
'get response-stream, and use a streamReader to read the content
Using s As IO.Stream = request.GetResponse().GetResponseStream()
Using sr As New IO.StreamReader(s)
'decode jsonData with javascript serializer
Dim jsonData = sr.ReadToEnd()
Stop
End Using
End Using
But, this just gives me the content of the web page at https://www.google.com/recaptcha. Not what I want. The Google page isn't very useful and I am stuck on where to go. I need some help either calling the Google verify service or if anyone has found another way to do this from ASP.NET.
I had just about given up when I ran across something unrelated that made me think about it again and in a different way. In my last attempt above, I was attempting to pass the private key and recaptcha response as the data, so I tried it in the create of the WebRequest and it worked. Here is the final solution:
Using the same HTML posted above, I created a function that I can call in the button click event where I check the Page.IsValid and call this function:
Private Function IsGoogleCaptchaValid() As Boolean
Try
Dim recaptchaResponse As String = Request.Form("g-recaptcha-response")
If Not String.IsNullOrEmpty(recaptchaResponse) Then
Dim request As Net.WebRequest = Net.WebRequest.Create("https://www.google.com/recaptcha/api/siteverify?secret=My Private Key&response=" + recaptchaResponse)
request.Method = "POST"
request.ContentType = "application/json; charset=utf-8"
Dim postData As String = ""
'get a reference to the request-stream, and write the postData to it
Using s As IO.Stream = request.GetRequestStream()
Using sw As New IO.StreamWriter(s)
sw.Write(postData)
End Using
End Using
''get response-stream, and use a streamReader to read the content
Using s As IO.Stream = request.GetResponse().GetResponseStream()
Using sr As New IO.StreamReader(s)
'decode jsonData with javascript serializer
Dim jsonData = sr.ReadToEnd()
If jsonData = "{" & vbLf & " ""success"": true" & vbLf & "}" Then
Return True
End If
End Using
End Using
End If
Catch ex As Exception
'Dont show the error
End Try
Return False
End Function
I'm sure there are improvements to be made to the code, but it works. I couldn't see adding references to some JSON libraries for reading one thing I just check the string.
Thank you for sharing this. It worked for me. I went ahead and converted it to C# (since that's what I was using) and added a few things.
I changed the validation step. I split the JSON string and evaluated if success was found where it should be.
I used the ConfigurationManager to store the ReCaptcha Keys.
Finally, I changed it from using a WebRequest to using and HttpClient. This cut the code in half because I don't need to read the stream now.
Feel free to use this code as well.
private static bool IsReCaptchaValid(string response)
{
if (string.IsNullOrWhiteSpace(response))
{
return false;
}
var client = new HttpClient();
string result =
client.GetStringAsync(string.Format("{0}?secret={1}&response={2}", ConfigurationManager.AppSettings["ReCaptchaValidationLink"],
ConfigurationManager.AppSettings["ReCaptchaSecretKey"], response)).Result;
string[] split = result.Split('\"');
return split[1] == "success";
}
I took a slightly different approach, using the data-callback option and a Session parameter. The following sits within the MainContent block of the .aspx file:
<asp:ScriptManager ID="scrEnablePage" EnablePageMethods="true" runat="server" />
<asp:Panel ID="pnlCaptcha" runat="server" Visible="true">
<div class="g-recaptcha"
data-sitekey='<asp:Literal ID="litKey" runat="server" Text="<%$ AppSettings:recaptchaPublicKey%>" />'
data-callback="handleCaptcha"></div>
</asp:Panel>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script type="text/javascript">
function handleCaptcha(e) {
PageMethods.RecaptchaValid(e);
location.reload(true);
}
</script>
Then in the code-behind:
Private Const GoogleUrl As String = "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}"
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
pnlCaptcha.Visible = Not (Session("VerifiedHuman") = "True")
...
End Sub
<System.Web.Services.WebMethod(EnableSession:=True)> _
Public Shared Sub RecaptchaValid(response As String)
Dim client As New System.Net.WebClient()
Dim outcome As Dictionary(Of String, String)
Dim result As String = String.Join(vbCrLf,
{"{", """success"": true", "}"})
Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer()
Dim url As String = String.Format(GoogleUrl,
ConfigurationManager.AppSettings.Get("recaptchaPrivateKey"),
response)
Try
result = client.DownloadString(url)
Catch ex As System.Net.WebException
Exit Sub ' Comment out to default to passing
End Try
outcome = serializer.Deserialize(Of Dictionary(Of String, String))(result)
HttpContext.Current.Session("VerifiedHuman") = outcome("success")
End Sub
Now in Page_Load you can check Session("VerifiedHuman") = "True" and update your page controls accordingly, hiding the panel with the Captcha control and showing the other appropriate items.
Note that this takes the keys from Web.config, i.e.
<configuration>
<appSettings>
<add key="recaptchaPublicKey" value="..." />
<add key="recaptchaPrivateKey" value="..." />
...
</appSettings>
...
</configuration>
This adds a few things. It converts the response from Google into a Json object, it adds a timeout on the verification request, and it adds a verification of the hostname (required by Google if sending requests from multiple domains and the domains aren't listed in the Google Admin area).
Imports Newtonsoft.Json
Public Class Google
Public Class ReCaptcha
Private Const secret_key = "YOUR_SECRET_KEY"
Public Shared Function Validate(Request As HttpRequest, hostname As String) As Boolean
Dim g_captcha_response = Request.Form("g-recaptcha-response")
If Not String.IsNullOrEmpty(g_captcha_response) Then
Dim response = ExecuteVerification(g_captcha_response)
If Not response.StartsWith("ERROR:") Then
Dim json_obj = JsonConvert.DeserializeObject(Of ValidateResponse)(response)
If json_obj.success Then
If json_obj.hostname.ToLower = hostname.ToLower Then Return True
End If
End If
End If
Return False
End Function
Private Shared Function ExecuteVerification(g_captcha_response As String) As String
Dim request As Net.WebRequest = Net.WebRequest.Create("https://www.google.com/recaptcha/api/siteverify?secret=" & secret_key & "&response=" & g_captcha_response)
request.Timeout = 5 * 1000 ' 5 Seconds to avoid getting locked up
request.Method = "POST"
request.ContentType = "application/json"
Try
Dim byteArray As Byte() = Encoding.UTF8.GetBytes("")
request.ContentLength = byteArray.Length
Dim dataStream As Stream = request.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
Dim response As Net.WebResponse = request.GetResponse()
dataStream = response.GetResponseStream()
Dim reader As New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
reader.Close()
response.Close()
Return responseFromServer
Catch ex As Exception
Return "ERROR: " & ex.Message
End Try
End Function
Public Class ValidateResponse
Public Property success As Boolean
Public Property challenge_ts As DateTime
Public Property hostname As String
<JsonProperty("error-codes")>
Public Property error_codes As List(Of String)
End Class
End Class
End Class
So in the button's Click event, just call:
If Google.ReCaptcha.Validate(Request, Request.Url.Host) Then
' good to go
Else
' validation failed
End If

How to manitain session values during HttpWebRequest?

In my code I'm sending a HttpWebRequest to a page in my website.
When request sends to this page, It doesn't maintain the Session values.
Below is the code, from where I'm generating the web request:
Public Overloads Shared Function ReadURL(ByVal sUrl As String) As String
Dim sBody As String
Dim oResponse As HttpWebResponse
Dim oRequest As HttpWebRequest
Dim oCookies As New CookieContainer
oRequest = WebRequest.Create("http://localhost:64802/inventory/purchase_order.aspx?id=5654")
oRequest.CookieContainer = oCookies
oResponse = oRequest.GetResponse()
Dim oReader As New StreamReader(oResponse.GetResponseStream())
sBody = oReader.ReadToEnd
oReader.Close()
oResponse.Close()
Return sBody
End Function
Below is the code written on Page_Load of Purchaseorder.aspx.vb:
iDomains_ID = Session("Domains_ID")
iLogin_ID = Session("Login_ID")
sPage = Request.Path
If Request.QueryString.Count > 0 Then sPage &= "?" & Request.QueryString.ToString()
sPage = shared01.Encrypt(sPage, Application("PK"))
If Not User.Identity.IsAuthenticated Or iLogin_ID = 0 Then
Response.Redirect("/login.aspx?page=" & sPage)
Exit Sub
End If
Above code doesn't gets the session values and it redirects to the login page.
So, how i can maintain the session on both pages during HttpWebRequest.
Looking for your replies.
EDIT
I've tried to use CookieContainer class as you can see in above code. But it doesn't work at all.
As an alternative, assuming the calling and called pages are in the same application, you could use the Server.Execute method to load the content of the page without making a separate request to the site:
Public Overloads Function ReadURL(ByVal sUrl As String) As String
Using writer As New StringWriter()
Server.Execute("~/inventory/purchase_order.aspx?id=5654", writer, False)
Return writer.ToString()
End Using
End Function
If I've understood you correctly, you're making a request from one page in your site to another, and you want to send the cookies from the current HttpRequest with your WebRequest?
In that case, you'll need to manually copy the cookies to the CookieContainer:
For Each key As String In Request.Cookies.AllKeys
Dim sourceCookie As HttpCookie = Request.Cookies(key)
Dim destCookie As New Cookie(sourceCookie.Name, sourceCookie.Value, sourceCookie.Path, "localhost")
destCookie.Expires = sourceCookie.Expires
destCookie.HttpOnly = sourceCookie.HttpOnly
destCookie.Secure = sourceCookie.Secure
oCookies.Add(destCookie)
Next
NB: You'll either need to make the ReadUrl function non-Shared, or pass the current HttpRequest as a parameter.
You'll also need to make sure the calling page has EnableSessionState="false" in the <%# Page ... %> directive, otherwise the page you're calling will hang trying to obtain the session lock.
Your code seems like you will need to make a request and a post. The first request will redirect you to your login page. The second will be a request where you post to the login page, which will start the session and (?) store information into the session variables. That post (to the login page) will then redirect you to the page you want.
I used code in this example http://www.codeproject.com/Articles/145122/Fetching-ASP-NET-authenticated-page-with-HTTPWebRe (I tweaked it a bit) to write an application to do this.

HttpWebRequest.GetResponse does not return AutoID for server side controls

In .NET by default the client side ID's, for server side controls, get concatenated with generated text.
For example:
<asp:TextBox ID="txtUser" runat="server">
would become...
<input type="text" id="ctl00_body_txbUser">
However when I use HttpWebRequest.GetResponse(objReq.Getresponse, HttpWebResponse) to request the same page the item comes back without the auto generated text.
<input type="text" id="txbUser">
Is it possible to use an HttpWebRequest object and GetResponse in such a way that it returns a response with the Auto generated ID's .NET uses for server side controls?
I am working with a 3rd party that has previously set up translation rules specific to ID, now we are attempting have the same rules work against an API call passed a string generated from the page. However, the string generated from the page does not have the same IDs.
Below is code being used to return the Web Page as a string.
Public Shared Function GetWebPageAsString(ByVal strURI As String, ByVal strPostData As String) As String
' Declare our variables. '
Dim objHttpRequest As HttpWebRequest
Dim PostBuffer() As Byte
Dim PostDataStream As Stream = Nothing
Dim objHttpResponse As HttpWebResponse = Nothing
Dim objStreamReader As StreamReader = Nothing
Dim strResponseText As String = ""
Try
' Create a new request. '
objHttpRequest = CType(WebRequest.Create(strURI), HttpWebRequest)
objHttpRequest.Timeout = 3000000
objHttpRequest.Method = "POST"
PostBuffer = Encoding.ASCII.GetBytes(strPostData)
objHttpRequest.ContentType = "application/x-www-form-urlencoded"
objHttpRequest.ContentLength = PostBuffer.Length
PostDataStream = objHttpRequest.GetRequestStream
PostDataStream.Write(PostBuffer, 0, PostBuffer.Length)
PostDataStream.Close()
' Get the response to our request as a stream object. '
objHttpResponse = CType(objHttpRequest.GetResponse, HttpWebResponse)
' Create a stream reader to read the data from the stream. '
objStreamReader = New StreamReader(objHttpResponse.GetResponseStream, Encoding.UTF8)
' Copy the text retrieved from the stream to a variable. '
strResponseText = objStreamReader.ReadToEnd()
' Close our objects. '
objStreamReader.Close()
objHttpResponse.Close()
Catch ex As Exception
strResponseText = strURI & " | " & strPostData
Throw (ex)
Finally
If Not objStreamReader Is Nothing Then
objStreamReader.Close()
End If
If Not PostDataStream Is Nothing Then
PostDataStream.Close()
End If
If Not objHttpResponse Is Nothing Then
objHttpResponse.Close()
End If
objHttpRequest = Nothing
PostBuffer = Nothing
PostDataStream = Nothing
objHttpResponse = Nothing
objStreamReader = Nothing
End Try
' Set return value. '
Return strResponseText
End Function
EDIT: Just to Clarify, I need the IDs to continue to be Auto generated by .NET. I understand that I could make them equal by setting the mode to Static. Unfortunately the 3rd Party we are working with has already created the rules for our current pages based on the IDs that were generated by .NET. Requesting the same page using the HTTPRequest object and pushing data into a stream. I am not seeing the Auto Generated IDs anymore, even though its the same page.
Create a clean master page and put your page in it. That should fix the IDs issue.

ASP.net: Scrape Part of webage

Dim url As New Uri("http://www.testpage.com")
If url.Scheme = Uri.UriSchemeHttp Then
'Create Request Object
Dim objRequest As HttpWebRequest = DirectCast(HttpWebRequest.Create(url), HttpWebRequest)
'Set Request Method
objRequest.Method = WebRequestMethods.Http.[Get]
'Get response from requested url
Dim objResponse As HttpWebResponse = DirectCast(objRequest.GetResponse(), HttpWebResponse)
'Read response in stream reader
Dim reader As New StreamReader(objResponse.GetResponseStream())
Dim tmp As String = reader.ReadToEnd()
objResponse.Close()
'Set response data to container
Label1.Text = tmp
End If
How Would I only scrape part of a webpage..The code succesfulyl get the full html content.
For Example..I want to scrape eveyrthing between <div id="content"> </div>
Once you have the page's full html content in a string variable, you can use Regular Expressions over this string to return the parts you want to extract.
Since you have not provided details on what you want to extract, I will provide you with a link on how to use Regular Expressions.
A short tutorial on Regular Expressions can be found here

Post XML to a web service

I have a web service, which accepts XML input. What I am trying to do is setup an aspx page which posts xml to the service. Here is my code so far, but I am getting an error 400 (bad request) when I try to submit...
Imports System.Net
Imports System.IO
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Submit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Submit.Click
Dim strDataToPost As String
Dim myWebRequest As WebRequest
Dim myRequestStream As Stream
Dim myStreamWriter As StreamWriter
Dim myWebResponse As WebResponse
Dim myResponseStream As Stream
Dim myStreamReader As StreamReader
' Create a new WebRequest which targets the web service method
myWebRequest = WebRequest.Create("http://foo/p09SoapHttpPort")
' Data to send
strDataToPost = DataToSend.Text & Server.UrlEncode(Now())
' Set the method and content type
With myWebRequest
.Method = "POST"
.ContentType = "text/xml"
.Timeout = -1
.ContentLength = strDataToPost.Length()
End With
' write our data to the Stream using the StreamWriter.
myRequestStream = myWebRequest.GetRequestStream()
myStreamWriter = New StreamWriter(myRequestStream)
myStreamWriter.Write(strDataToPost)
myStreamWriter.Flush()
myStreamWriter.Close()
myRequestStream.Close()
' Get the response from the remote server.
myWebResponse = myWebRequest.GetResponse()
' Get the server's response status
myResponseStream = myWebResponse.GetResponseStream()
myStreamReader = New StreamReader(myResponseStream)
ResponseLabel.Text = myStreamReader.ReadToEnd()
myStreamReader.Close()
myResponseStream.Close()
' Close the WebResponse
myWebResponse.Close()
End Sub
End Class
If anyone knows of any good web resources on how to upload .xml files to a web service method that would also be a great help and would answer this question as I can re-work it that way.
Thanks.
P.S in the last edit, I modified the code to have .contentlength (thanks for the assistance). Unfortunately after this I am still getting 'Bad Request'. If anyone can confirm / disconfirm my code should be working, I will start investigating the service itself.
The data you're trying to post might look a little funny if you're concatenating a time string to it:
strDataToPost = DataToSend.Text & Server.UrlEncode(Now())
If DataToSend is proper XML, then you're adding the Url Encoding of Now() which makes me think it will no longer be valid XML.
Check to make sure your StreamWriter is not inserting additional characters (CR, LF). If it does, then the length you're sending does not correspond to the actual data, but that probably wouldn't have caused a problem before you started sending the content length.
Is your web service configuration to accept XML directly? I'm wondering if you might have to encapsulate the XML in multipart/form-data in order for your web service to accept it.
I'm not a web service expert, but I compared your code to some working code I have, and the only relevant difference is that you are not setting the ContentLength of your request.
myWebRequest.ContentLength = strDataToPost.Length()

Resources