Pass parameters to a webmethod from querystring - asp.net

guys. I'm developing a website with ASP and VB.NET 4. I'm also using the FullCalendar jQuery plugin, but I have a trouble: catching a parameter from querystring to the webmethod in the .asmx. I've tried to refer the querystring property with the Request.QueryString() and it doesn't work.
Here's the webmethod:
<%# WebService Language="VB" Class="wbsCalendario" %>
Imports System.Web
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Web.Script.Services
Imports System.Collections.Generic
Imports System.Configuration.ConfigurationManager
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)>
<ScriptService> _
Public Class wbsCalendario
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function ListarEventos(ByVal starte As String, ByVal ende As String, ByVal v As String) As List(Of CalendarioEvento)
Dim conexaoSql As New SqlConnection(ConnectionStrings("praeConnectionString").ConnectionString)
Dim comandoSql As SqlCommand = New SqlCommand("spListarEventosCalendario", conexaoSql)
comandoSql.CommandType = CommandType.StoredProcedure
comandoSql.Parameters.AddWithValue("#bitPendentes", 0)
comandoSql.Parameters.AddWithValue("#agendamentos", "188,135")
comandoSql.Parameters.AddWithValue("#start", FromUnixTimespan(starte))
comandoSql.Parameters.AddWithValue("#end", FromUnixTimespan(ende))
comandoSql.Parameters.AddWithValue("#veiculo", v)
Dim eventos As List(Of CalendarioEvento) = New List(Of CalendarioEvento)
Try
conexaoSql.Open()
Dim sdrEventos As SqlDataReader = comandoSql.ExecuteReader
While sdrEventos.Read
Dim evento As New CalendarioEvento
evento.title = StrConv(sdrEventos("vchNome").ToString, VbStrConv.ProperCase)
evento.start = ToUnixTimespan(Convert.ToDateTime(sdrEventos("vchData") + " " + sdrEventos("vchHora")))
eventos.Add(evento)
End While
Catch ex As Exception
Finally
conexaoSql.Close()
End Try
comandoSql.Parameters("#bitPendentes").Value = 1
Try
conexaoSql.Open()
Dim sdrEventos As SqlDataReader = comandoSql.ExecuteReader
While sdrEventos.Read
Dim evento As New CalendarioEvento
evento.title = StrConv(sdrEventos("vchNome").ToString, VbStrConv.ProperCase)
evento.start = ToUnixTimespan(Convert.ToDateTime(sdrEventos("vchData") + " " + sdrEventos("vchHora")))
evento.color = "#6AB0D8"
eventos.Add(evento)
End While
Catch ex As Exception
Finally
conexaoSql.Close()
End Try
Return eventos
End Function
Private Shared Function ToUnixTimespan(ByVal d As DateTime) As Long
Dim time As New TimeSpan()
time = d.ToUniversalTime().Subtract(New DateTime(1970, 1, 1, 0, 0, 0))
Return CType(Math.Truncate(time.TotalSeconds), Int64)
End Function
Private Shared Function FromUnixTimespan(ByVal s As String) As DateTime
Dim time As DateTime = New DateTime(1970, 1, 1, 0, 0, 0)
Return time.AddSeconds(s)
End Function
End Class
Can someone help me?
Thanks.

The values in the query string are automatically translated into arguments defined on the webmethod.
If you had this Webmethod:
<WebMethod()> Public Sub DoWork(arg1 As Integer, arg2 As String)
And called it by a url of:
http://domain/webservice.asmx/DoWork?arg=2&arg2=hello
Those two querystring parameters would be translated into the two arguments arg1 and arg2, which could be referenced as normal within the DoWork() method.

Related

QueryStringModule with FriendlyUrls does not working

Good morning, I need to encrypt my querystring and i found an interesting method in this link and I convert it in vb.net:
Imports System
Imports System.IO
Imports System.Web
Imports System.Text
Imports System.Security.Cryptography
Public Class QueryStringModule
Implements IHttpModule
Public Sub Dispose() Implements IHttpModule.Dispose
End Sub
Public Sub Init(ByVal context As HttpApplication) Implements IHttpModule.Init
AddHandler context.BeginRequest, New EventHandler(AddressOf context_BeginRequest)
End Sub
Private Const PARAMETER_NAME As String = "enc="
Private Const ENCRYPTION_KEY As String = "key"
Private Sub context_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim context As HttpContext = HttpContext.Current
If context.Request.Url.OriginalString.Contains("aspx") AndAlso context.Request.RawUrl.Contains("?") Then
Dim query As String = ExtractQuery(context.Request.RawUrl)
Dim path As String = GetVirtualPath()
If query.StartsWith(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase) Then
Dim rawQuery As String = query.Replace(PARAMETER_NAME, String.Empty)
Dim decryptedQuery As String = Decrypt(rawQuery)
context.RewritePath(path, String.Empty, decryptedQuery)
ElseIf context.Request.HttpMethod = "GET" Then
Dim encryptedQuery As String = Encrypt(query)
context.Response.Redirect(path & encryptedQuery)
End If
End If
End Sub
Private Shared Function GetVirtualPath() As String
Dim path As String = HttpContext.Current.Request.RawUrl
path = path.Substring(0, path.IndexOf("?"))
path = path.Substring(path.LastIndexOf("/") + 1)
Return path
End Function
Private Shared Function ExtractQuery(ByVal url As String) As String
Dim index As Integer = url.IndexOf("?") + 1
Return url.Substring(index)
End Function
Private ReadOnly Shared SALT As Byte() = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString())
Public Shared Function Encrypt(ByVal inputText As String) As String
Dim rijndaelCipher As RijndaelManaged = New RijndaelManaged()
Dim plainText As Byte() = Encoding.Unicode.GetBytes(inputText)
Dim SecretKey As PasswordDeriveBytes = New PasswordDeriveBytes(ENCRYPTION_KEY, SALT)
Using encryptor As ICryptoTransform = rijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16))
Using memoryStream As MemoryStream = New MemoryStream()
Using cryptoStream As CryptoStream = New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainText, 0, plainText.Length)
cryptoStream.FlushFinalBlock()
Return "?" & PARAMETER_NAME & Convert.ToBase64String(memoryStream.ToArray())
End Using
End Using
End Using
End Function
Public Shared Function Decrypt(ByVal inputText As String) As String
Dim rijndaelCipher As RijndaelManaged = New RijndaelManaged()
Dim encryptedData As Byte() = Convert.FromBase64String(inputText)
Dim secretKey As PasswordDeriveBytes = New PasswordDeriveBytes(ENCRYPTION_KEY, SALT)
Using decryptor As ICryptoTransform = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16))
Using memoryStream As MemoryStream = New MemoryStream(encryptedData)
Using cryptoStream As CryptoStream = New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
Dim plainText As Byte() = New Byte(encryptedData.Length - 1) {}
Dim decryptedCount As Integer = cryptoStream.Read(plainText, 0, plainText.Length)
Return Encoding.Unicode.GetString(plainText, 0, decryptedCount)
End Using
End Using
End Using
End Function
End Class
but also my project use FriendlyUrls and I figured out that with FriendlyUrls the things does not working and always return the url without the extension ".aspx" but with the querystring not encrypted
Imports System.Web.Routing
Imports Microsoft.AspNet.FriendlyUrls
Public Module RouteConfig
Sub RegisterRoutes(ByVal routes As RouteCollection)
Dim settings As FriendlyUrlSettings = New FriendlyUrlSettings() With {
.AutoRedirectMode = RedirectMode.Permanent
}
routes.EnableFriendlyUrls(settings)
End Sub
End Module
of course if I set .AutoRedirectMode to Off it works but without friendlyurls.
Am I doing something wrong?
EDIT 09/10/2019:
We figured out that remove the test of OriginalString.Contains("aspx") in the context_BeginRequest the encryption works, now the code is like:
Private Sub context_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim context As HttpContext = HttpContext.Current
If context.Request.RawUrl.Contains("?") Then
Dim query As String = ExtractQuery(context.Request.RawUrl)
Dim path As String = GetVirtualPath()
If query.StartsWith(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase) Then
Dim rawQuery As String = query.Replace(PARAMETER_NAME, String.Empty)
Dim decryptedQuery As String = Decrypt(rawQuery)
context.RewritePath(path, String.Empty, decryptedQuery)
ElseIf context.Request.HttpMethod = "GET" Then
Dim encryptedQuery As String = Encrypt(query)
context.Response.Redirect(path & encryptedQuery)
End If
End If
End Sub
But now the question is: there is other method to target an aspx page without test the extension? I think there is a risk that targeting things that not should target like "ashx" or cache-busting code that use querystring.

Microsoft Translator API v3, ASP.NET VB.NET

I am trying to call on the MS Translator API through an ASP.NET function to translate various strings from a database.
All examples from MS are given in C# so I throw into a converter and go from there.
From my searching I'm pretty sure this is an async/await issue. I have also tried setting strString to different things at different times but it throws the same error as if I'm not awaiting properly.
From the aspx page I have this:
<%# functions.translate(Eval("Description").ToString) %>
Description is a field from a database and shows properly if not passed to the translate function. I have other functions that I call to do various things and work properly.
In my functions.vb I have:
Public Class TranslationResult
Public Property Translations As Translation()
End Class
Public Class Translation
Public Property Text As String
Public Property [To] As String
End Class
Public Class functions
Public Shared Async Function translate(strString As String) As Task(Of String)
Dim host As String = "https://api.cognitive.microsofttranslator.com"
Dim route As String = "/translate?api-version=3.0&to=fr"
Dim key As String = "0000000000000000000000000"
Dim body As Object() = New Object() {New With {Key .Text = strString}}
Dim requestBody = JsonConvert.SerializeObject(body)
Using client = New HttpClient()
Using request = New HttpRequestMessage()
request.Method = HttpMethod.Post
request.RequestUri = New Uri(host & route)
request.Content = New StringContent(requestBody, Encoding.UTF8, "application/json")
request.Headers.Add("Ocp-Apim-Subscription-Key", key)
Dim response As HttpResponseMessage = Await client.SendAsync(request).ConfigureAwait(False)
Dim result As String = Await response.Content.ReadAsStringAsync()
Dim deserializedOutput As TranslationResult() = JsonConvert.DeserializeObject(Of TranslationResult())(result)
For Each o As TranslationResult In deserializedOutput
For Each t As Translation In o.Translations
strString = t.Text
Next
Next
End Using
End Using
Return strString
End Function
The error I'm getting is on the web page showing System.Threading.Tasks.Task`1[System.String] when I'm expecting a translated string.
I used your code as base and got it working. Just using a simple Webform.
Didn't change anything in the code, but I was prompted to add
Imports System.Net.Http
By Visual studio 2019
The final entire webform codebehind vb.aspx looks like this:
Imports System.Net.Http
Imports System.Threading.Tasks
Imports Newtonsoft.Json
Public Class microsoftTranslator
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
dim translatedText = functions.translate( "This is going to be one, two, three in french").Result
End Sub
Public Class TranslationResult
Public Property Translations As Translation()
End Class
Public Class Translation
Public Property Text As String
Public Property [To] As String
End Class
Public Class functions
Public Shared Async Function translate(strString As String) As Task(Of String)
Dim host As String = "https://api.cognitive.microsofttranslator.com"
Dim route As String = "/translate?api-version=3.0&to=fr"
Dim key As String = "0000000000000000000000000"
Dim body As Object() = New Object() {New With {Key .Text = strString}}
Dim requestBody = JsonConvert.SerializeObject(body)
Using client = New HttpClient()
Using request = New HttpRequestMessage()
request.Method = HttpMethod.Post
request.RequestUri = New Uri(host & route)
request.Content = New StringContent(requestBody, Encoding.UTF8, "application/json")
request.Headers.Add("Ocp-Apim-Subscription-Key", key)
Dim response As HttpResponseMessage = Await client.SendAsync(request).ConfigureAwait(False)
Dim result As String = Await response.Content.ReadAsStringAsync()
Dim deserializedOutput As TranslationResult() = JsonConvert.DeserializeObject(Of TranslationResult())(result)
For Each o As TranslationResult In deserializedOutput
For Each t As Translation In o.Translations
strString = t.Text
Next
Next
End Using
End Using
Return strString
End Function
end class
End Class
To make it wait for the async result look at the .result property
<%# Page Language="VB" %>
<%# Import Namespace="System.IO" %>
<%# Import Namespace="System.Net" %>
<!DOCTYPE html>
<script runat="server">
Protected Sub Page_Load(sender As Object, e As EventArgs)
Dim APIUrlToSend As String = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=en&to=de"
Dim MyMainRequest As HttpWebRequest = CType(HttpWebRequest.Create(APIUrlToSend), HttpWebRequest)
MyMainRequest.Headers.Add("Ocp-Apim-Subscription-Key", "YOUR API CODE")
MyMainRequest.ContentType = "application/json; charset=utf-8"
MyMainRequest.Method = "POST"
' Send request
Dim MyJavaScriptSerializer = New System.Web.Script.Serialization.JavaScriptSerializer()
Dim TextToTranslate As String = MyJavaScriptSerializer.Serialize("Text to translate")
Dim MyMainRequestBody As String = "[{ Text: " & TextToTranslate & " }]"
Dim MyMainRequestBytesData As Byte() = Encoding.UTF8.GetBytes(MyMainRequestBody)
MyMainRequest.ContentLength = MyMainRequestBytesData.Length
Using RequestWriteStream = MyMainRequest.GetRequestStream()
RequestWriteStream.Write(MyMainRequestBytesData, 0, MyMainRequestBytesData.Length)
End Using
Dim MyFinalResponse As HttpWebResponse = MyMainRequest.GetResponse()
Dim MyFinalResponseStream As Stream = MyFinalResponse.GetResponseStream
Dim MyFinalResponseStreamReader As New StreamReader(MyFinalResponseStream, Encoding.GetEncoding("utf-8"))
Page.Response.Write(MyFinalResponseStreamReader.ReadToEnd())
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>

Google reCaptcha V2 Implementation VB.net

Having a hard time getting reCaptcha to validate on my site :(
I have tried to find other sources for VB.net implementations, but haven't had much luck. Here is what I have tried...
default.aspx.vb
Imports System.Collections.Generic
Imports System.Linq
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Data
Imports System.Net
Imports System.Text
Imports System.IO
Imports System.Web.Script.Serialization
Public Class _Default
Inherits System.Web.UI.Page
Sub reCaptcha_Click(ByVal sender As Object, ByVal e As EventArgs)
If (capValidate()) Then
MsgBox("Valid Recaptcha")
Else
MsgBox("Not Valid Recaptcha")
End If
End Sub
Public Function capValidate() As Boolean
Dim Response As String = Request("g-captcha-response")
Dim Valid As Boolean = False
Dim req As HttpWebRequest = DirectCast(WebRequest.Create(Convert.ToString("https://www.google.com/recaptcha/api/siteverify?secret=THIS IS WHERE MY KEY IS&response=") & Response), HttpWebRequest)
Try
Using wResponse As WebResponse = req.GetResponse()
Using readStream As New StreamReader(wResponse.GetResponseStream())
Dim jsonResponse As String = readStream.ReadToEnd()
Dim js As New JavaScriptSerializer()
Dim data As MyObject = js.Deserialize(Of MyObject)(jsonResponse)
Valid = Convert.ToBoolean(data.success)
Return Valid
End Using
End Using
Catch ex As Exception
Return False
End Try
End Function
Public Class MyObject
Public Property success() As String
Get
Return m_success
End Get
Set(value As String)
m_success = Value
End Set
End Property
Private m_success As String
End Class
And my front page...
<div class="g-recaptcha"
data-sitekey="THIS IS WHERE MY SITE KEY IS"></div>
<asp:Button ID="btnLogin" CssClass="captcha_click" runat="server" Text="Check Recaptcha" OnClick="reCaptcha_Click" TabIndex ="4"/>
My message boxes always return "not a valid recaptcha"
Can anyone shed some light on why I cannot get a valid recaptcha return?
Thanks!
Try:
Dim Response As String = Request("g-recaptcha-response")
Note the re

vb.net using ashx handler to get image from SQL Server

I have employee images stored in my EMPPhotos table on SQL Server 2008 R2 in an image datatype. I created a generic handler to get the image from the table and send it to the page. It does not work. I have tested the query itself and I am getting data.
The handler:
<%# WebHandler Language="VB" Class="EmpImageHandler" %>
Imports System
Imports System.Web
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Public Class EmpImageHandler : Implements IHttpHandler
Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
'context.Response.ContentType = "text/bmp"
'context.Response.Write("Hello World")
context.Response.ContentType = "text/bmp"
Dim img As Image = GetImage(context.Request.QueryString("id"))
img.Save(context.Response.OutputStream, ImageFormat.Bmp)
End Sub
Private Function GetImage(inID As Long) As Image
Dim ms As MemoryStream = New MemoryStream
Dim cnSTR As New clsConnections
Dim cn As New SqlConnection(cnSTR.ConnectToDB("AgencyStaff"))
Try
cn.Open()
Catch ex As Exception
End Try
Dim ssql As String = "Select BMPPhoto From EMPPhotos where empid = " & inID
Dim CMD As SqlCommand = New SqlCommand(ssql, cn)
Dim dr As SqlDataReader = CMD.ExecuteReader
dr.Read()
Dim img() As Byte = CType(dr("BMPPhoto"), Byte())
ms = New MemoryStream(img, False)
Return Image.FromStream(ms)
End Function
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
End Class
Thanks in advance for your assistance.
Change your ContentType.
From:
context.Response.ContentType = "text/bmp"
To:
context.Response.ContentType = "image/bmp"

Design-time trouble with ASP.NET v2.0 Custom Control, with List<T> for child items

Folks,
I am having a devil of a time with a custom control. The control is very simple - it just displays a list of "StepItems" (rendered as table rows), each with an icon. When I first drag it onto a page, and add StepItems to its collection, it renders perfectly. If I provide some text for its Header property, that also renders perfectly.
If I then look at the HTML source view, and then back to the design view, I get an error where my control should be. There are two kinds of errors:
If I set the .Header property, the error reads "StepProgressControl1:'someheadertext' could not be set on property 'Header'.
If I don't set the .Header, but add StepItems to the collection, I get this: "ErrorStepProgressControl1:'StepItems' could not be initialized. Details: Method not found: 'System.Collections.Generic.List`1 StepProgressControl.TKC.Experiment.StepProgressControl.get_StepItems()'."
The complete code for my custom control is below. If you can provide any help, thank you a great deal!
Tom
'================================
Imports System
Imports System.Collections
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Security.Permissions
Imports System.ComponentModel
Namespace TKC.Experiment
' THIS IS THE INTERNAL "CHILD" ELEMENT
< _
PersistenceMode(PersistenceMode.InnerProperty), _
TypeConverter(GetType(StepItemConverter)) _
> _
Public Class StepItem
Private _name As String
Public Sub New()
Me.New("")
End Sub
Public Sub New(ByVal name As String)
Me._name = name
End Sub
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
End Class
'=====================================================================
' THIS IS THE ACTUAL "PARENT" WEB CONTROL
< _
ParseChildren(True, "StepItems"), _
PersistChildren(False) _
> _
Public NotInheritable Class StepProgressControl
Inherits WebControl
Private _header As String = String.Empty
Private _stepItems As New List(Of StepItem)
Public Sub New()
Me.Header = "StepProgressControl"
End Sub
< _
PersistenceMode(PersistenceMode.Attribute) _
> _
Public Property Header() As String
Get
Return _header
End Get
Set(ByVal value As String)
_header = value
End Set
End Property
< _
DesignerSerializationVisibility(DesignerSerializationVisibility.Content), _
PersistenceMode(PersistenceMode.InnerProperty) _
> _
Public ReadOnly Property StepItems() As List(Of StepItem)
Get
If _stepItems Is Nothing Then
_stepItems = New List(Of StepItem)
End If
Return _stepItems
End Get
'Set(ByVal value As List(of stepitem))
' _stepItems = value
'End Set
End Property
Public Overrides Sub RenderControl(ByVal writer As System.Web.UI.HtmlTextWriter)
MyBase.RenderControl(writer)
Dim label As New Label()
label.Text = Header
label.RenderControl(writer)
Dim table As New Table()
Dim htr As New TableRow()
Dim hcell1 As New TableHeaderCell()
hcell1.Text = "Name"
htr.Cells.Add(hcell1)
Dim hcell2 As New TableHeaderCell()
hcell2.Text = "Title"
htr.Cells.Add(hcell2)
table.BorderWidth = Unit.Pixel(0)
Dim stepItem As StepItem
For Each stepItem In StepItems
Dim tr As New TableRow()
Dim cell1 As New TableCell()
Dim img As New HtmlImage
img.Src = ""
img.Alt = ""
cell1.Controls.Add(img)
tr.Cells.Add(cell1)
Dim cell2 As New TableCell()
cell2.Text = stepItem.Name
tr.Cells.Add(cell2)
table.Rows.Add(tr)
Next stepItem
table.RenderControl(writer)
End Sub
End Class
'========================================
'THIS IS A "TYPE CONVERTER" - JUST A COSMETIC THING, NOT CAUSING TROUBLE...
Public Class StepItemConverter
Inherits TypeConverter
Public Overloads Overrides Function ConvertTo(ByVal context As ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object
Dim obj As StepItem = DirectCast(value, StepItem)
Return obj.Name
End Function
End Class
End Namespace
You will want to implement your own Collection object to represent the list - otherwise the designer will not display it properly.
See the ICollection, IEnumerable, etc. interfaces.

Resources