I'm trying to retrieve the values from the Url using the second function. the first function function passes in the checkedValue variable and the second should check to see if the category is there and if it is return the value.
Imports System.Web.HttpRequest
Public Class ReviewPageDefault
Inherits Page
Shared Function GetProductId()
Dim util As New Utilities
Dim product = ""
If util.CheckString("schoolid") = "" And util.CheckString("stockid") = "" Then
product = (util.CheckString("stock"))
ElseIf util.CheckString("stock") = "" And util.CheckString("stockid") = "" Then
product = (util.CheckString("FN"))
Else
Dim stockId = util.CheckString("stockid")
product = stockId
End If
Return product
End Function
End Class
Public Class Utilities
Inherits Page
Public Function CheckString(checkedValue As String)
Dim check = ""
If Request.QueryString(checkedValue) Is Nothing Then
Else
check = Request.QueryString(checkedValue)
End If
Return check
End Function
End Class
However whenever I try to test the page I get the error
System.Web.HttpException: Request is not available in this context
The code is located in the code behind for an asp.net page, that attempts to retrieve the product value
<script>
var product = '<%= ReviewPageDefault.GetProductId()%>';
</script>
I've searched the internet over and have found nothing, any help or advice is appreciated
Have your Utilities class take the Request as parameter instead of inheriting from Page:
Public Class Utilities
Public Function CheckString(checkedValue As String, request as HttpRequest)
Dim check = ""
If request.QueryString(checkedValue) Is Nothing Then
Else
check = request.QueryString(checkedValue)
End If
Return check
End Function
End Class
and when calling it pass the Request from the main page:
util.CheckString("stock", Request)
or make it an extension method on the HttpRequest class so that you can use it like this:
Request.CheckString("stock")
Related
I am using Window Application for my project. There is situation where i need to define string enum and using it in my project.
i.e.
Dim PersonalInfo As String = "Personal Info"
Dim Contanct As String = "Personal Contanct"
Public Enum Test
PersonalInfo
Contanct
End Enum
Now i want value of that variable PersonalInfo and Contract as "Personal Info" and "Personal Contanct".
How can i get this value using ENUM? or anyother way to do it.
Thanks in advance...
For non-integer values, Const in a Structure (or Class) can be used instead:
Structure Test
Const PersonalInfo = "Personal Info"
Const Contanct = "Personal Contanct"
End Structure
or in a Module for direct access without the Test. part:
Module Test
Public Const PersonalInfo = "Personal Info"
Public Const Contanct = "Personal Contanct"
End Module
In some cases, the variable name can be used as a value:
Enum Test
Personal_Info
Personal_Contanct
End Enum
Dim PersonalInfo As String = Test.Personal_Info.ToString.Replace("_"c, " "c)
' or in Visual Studio 2015 and newer:
Dim Contanct As String = NameOf(Test.Personal_Contanct).Replace("_"c, " "c)
You could just create a new type
''' <completionlist cref="Test"/>
Class Test
Private Key As String
Public Shared ReadOnly Contact As Test = New Test("Personal Contanct")
Public Shared ReadOnly PersonalInfo As Test = New Test("Personal Info")
Private Sub New(key as String)
Me.Key = key
End Sub
Public Overrides Function ToString() As String
Return Me.Key
End Function
End Class
and when you use it, it kinda looks like an enum:
Sub Main
DoSomething(Test.Contact)
DoSomething(Test.PersonalInfo)
End Sub
Sub DoSomething(test As Test)
Console.WriteLine(test.ToString())
End Sub
output:
Personal Contanct
Personal Info
How about using Tagging. Something like:
Public Enum MyEnum
<StringValue("Personal Contact")>Contact
<StringValue("My PersonalInfo")>PersonalInfo
End Enum
You would have to write the StringValue attribute as:
Public Class StringValueAttribute
Inherits Attribute
Public Property Value As String
Public Sub New(ByVal val As String)
Value = val
End Sub
End Class
To get it out:
Public Function GetEnumByStringValueAttribute(value As String, enumType As Type) As Object
For Each val As [Enum] In [Enum].GetValues(enumType)
Dim fi As FieldInfo = enumType.GetField(val.ToString())
Dim attributes As StringValueAttribute() = DirectCast(fi.GetCustomAttributes(GetType(StringValueAttribute), False), StringValueAttribute())
Dim attr As StringValueAttribute = attributes(0)
If attr.Value = value Then
Return val
End If
Next
Throw New ArgumentException("The value '" & value & "' is not supported.")
End Function
Public Function GetEnumByStringValueAttribute(Of YourEnumType)(value As String) As YourEnumType
Return CType(GetEnumByStringValueAttribute(value, GetType(YourEnumType)), YourEnumType)
End Function
And then a call to get the Enum (using string attribute):
Dim mEnum as MyEnum = GetEnumByStringValueAttribute(Of MyEnum)("Personal Contact")
To get the "Attribute" value out (removed handling 'Nothing' for clarity):
Public Function GetEnumValue(Of YourEnumType)(p As YourEnumType) As String
Return DirectCast(Attribute.GetCustomAttribute(ForValue(p), GetType(StringValueAttribute)), StringValueAttribute).Value
End Function
Private Function ForValue(Of YourEnumType)(p As YourEnumType) As MemberInfo
Return GetType(YourEnumType).GetField([Enum].GetName(GetType(YourEnumType), p))
End Function
And the call to get the string attribute (using Enum):
Dim strValue as String = GetEnumValue(Of MyEnum)(MyEnum.Contact)
How can i get this value using ENUM? or anyother way to do it.
There are three common ways of mapping enum values to strings:
Use a Dictionary(Of YourEnumType, String)
Decorate the enum values with attributes (e.g. DescriptionAttribute) and fetch them with reflection
Use a Switch statement
The first of these options is probably the simplest, in my view.
I know this is an old post put I found a nice solution that worth sharing:
''' <summary>
''' Gives acces to strings paths that are used often in the application
''' </summary>
Public NotInheritable Class Link
Public Const lrAutoSpeed As String = "scVirtualMaster<.lrAutoSpeed>"
Public Const eSimpleStatus As String = "scMachineControl<.eSimpleStatus>"
Public Const xLivebitHMI As String = "scMachineControl<.xLivebitHMI>"
Public Const xChangeCycleActive As String = "scMachineControl<.xChangeCycleActive>"
End Class
Usage:
'Can be anywhere in you applicaiton:
Link.xChangeCycleActive
This prevents unwanted extra coding, it's easy to maintain and I think this minimizes extra processor overhead.
Also visual studio shows the string attributes right after you type "Link"
just like if it is a regular Enum
If all you want to do is display the enums in a list or combo, you can use tagging such as
Private Enum MyEnum
Select_an_option___
__ACCOUNTS__
Invoices0
Review_Invoice
__MEETINGS__
Scheduled_Meetings0
Open_Meeting
Cancelled_Meetings0
Current_Meetings0
End Enum
Then pull the MyEnum into a string and use Replace (or Regex) to replace the tags: "___" with "...", "__" with "**", "_" with " ", and remove trailing numbers. Then repack it up into an array and dump it into a combobox which will look like:
Select an option...
**ACCOUNTS**
Invoices
Review Invoice
**MEETINGS**
Scheduled Meetings
Open Meeting
Cancelled Meetings
Current Meetings
(You can use the numbers to, say, disable a text field for inputting an invoice number or meeting room. In the example, Review Invoice and Open Meeting might be expecting additional input so a text box might be enabled for those selections.)
When you parse the selected combo item, the enumeration will work as expected but you only really need to add a single line of code - the text replacement - to get the combo to look as you wish.
(The explanation is about 10 times as involved as the actual solution!)
This technique from Microsoft - "How to: Determine the String Associated with an Enumeration Value (Visual Basic)" - will be useful in some situations (it didn't help with mine unfortunately though :( ). Microsoft's example:
VB:
Public Enum flavorEnum
salty
sweet
sour
bitter
End Enum
Private Sub TestMethod()
MsgBox("The strings in the flavorEnum are:")
Dim i As String
For Each i In [Enum].GetNames(GetType(flavorEnum))
MsgBox(i)
Next
End Sub
longtime lurker, first time poster.
I am writing a WEBAPI and have some questions on the default output. I know output is based upon the ACCEPT in the request (json/xml etc). However, I have a need to completely control the output. I will format my own XML.
I have found several examples on how to do this, most in .cs so I am trying to change this to vb.net.
Here is one of my tests:
Public Function Authenticate() As HttpResponseMessage
Dim XML As String = "Message content"
Return New HttpResponseMessage() With { _
.Content = New StringContent(XML, Encoding.UTF8, "application/xml") _
}
End Function
When In my calling function, when I try:
Return Authenticate()
I get an error:
Value of type 'System.net.http.httpresponsemessage' cannot be converted to String
It seems like this is used quite a bit in .cs as I see lots of examples. Anyone have an idea of how to accomplish this in VB.NET?
My Controller:
<HttpGet, HttpPost> _
Public Function [Login](<FromUri> staff As login) As String
Dim xmlheader As String
Dim head As New header
xmlheader = head.addheader()
If staff.password = "" Then
Dim result As String
Dim err As New messages
result = xmlheader & err.geterror("password")
Return Authenticate()
End If
End Function
Thank you!
Your problem is clear. YOu have
Public Function [Login](<FromUri> staff As login) As String
You need to declare your controller as
Public Function [Login](<FromUri> staff As login) As HttpResponseMessage
It looks like you are trying to use the return value from Authenticate as a string. I don't know exactly what you are trying to do, but I think .ToString() will work.
Dim foo As String = Authenticate().ToString()
' Do whatever with foo here...use it as a string
I would like to feed data to a proxy which creates a soap XML request formatted as below:
<dat:MusicCollection>
<!--Zero or more repetitions:-->
<dat:Song>
<dat:songUserkey>TakemeHome</dat:songUserkey>
</dat:Song>
</dat:MusicCollection>
I have written the file to call the service and provide the details as below:
dim ucizi1 as SongRequest 'this is the request class in the proxy
dim Songs as Song = New Song
Songs.songUserKey = "TakeMeHome"
dim ucz
ucz = Songs.SongUserKey
ucizi1.SongCollection.Add(ucz)
The MusicCollection class is as follows:
<System.Diagnostics.DebuggerStepThroughAttribute(), _
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), _
System.Runtime.Serialization.CollectionDataContractAttribute(Name:="ProductCollection", [Namespace]:="http://ucizi.Musicservice/DataContracts", ItemName:="Song")> _
Public Class SongCollection
Inherits System.Collections.Generic.List(Of ucizi.Music.DataContracts.Song)
End Class
The song class is as follows:
<System.Diagnostics.DebuggerStepThroughAttribute(), _
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0"), _
System.Runtime.Serialization.DataContractAttribute(Name:="Product", [Namespace]:="http://Ucizi.Music/DataContracts")> _
Partial Public Class Product
Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject
Private extensionDataField As System.Runtime.Serialization.ExtensionDataObject
Private SongUserkeyField As String
Public Property ExtensionData() As System.Runtime.Serialization.ExtensionDataObject Implements System.Runtime.Serialization.IExtensibleDataObject.ExtensionData
Get
Return Me.extensionDataField
End Get
Set
Me.extensionDataField = value
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute(IsRequired:=true)> _
Public Property SongUserkey() As String
Get
Return Me.SongUserkeyField
End Get
Set
Me.SongUserkeyField = value
End Set
End Property
End Class
However, when I run this code, I get an error: unable to cast object of type 'system.string' to type 'ucizi.music.DataContracts.Song'.
I cant see where this error is coming from, can some1 please help me and advise how I can correct this.
In lines
Songs.songUserKey = "TakeMeHome"
dim ucz
ucz = Songs.SongUserKey
ucizi.SongCollection.Add(ucz)
you set ucz to be SongUserKey - which is string.
Then, you add it to collection SongCollection
Public Class SongCollection
Inherits System.Collections.Generic.List(Of ucizi.Music.DataContracts.Song)
End Class
Which is expected Song
added the following code after the Songs.songUserKey = "TakeMeHome"
dim ucizi2 as songCollection
ucizi2.Add(song)
ucizi1.songcollection = ucizi2
This sorted the problem smoothly. You guys opened my eyes.
I am developing app where I need to capture an Information from Webpage after giving credentials automatically. Some how I managed to do Automatic login and redirection of page. Here is my code :
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://abcd.com.au/categories/A_dfn/sdf");
HttpWebResponse res = req.GetResponse() as HttpWebResponse;
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[10000];
Stream resStream = res.GetResponseStream();
string s = null;
int c = 0;
do
{
c = resStream.Read(buf, 0, buf.Length);
if (c != 0) {
s = ASCIIEncoding.ASCII.GetString(buf, 0, c);
sb.Append(s);
}
} while (c > 0);
string oldhead = "class=\"login_button\">";
string newhead = "class=\"login_button\"> <script type=\"text/javascript\">document.getElementById('btn').click()</script>";
sb.Replace(oldhead, newhead);
string oldbtn = "value=\"Submit\"";
string newbtn = "value=\"Submit\" id=\"btn\" ";
sb.Replace(oldbtn, newbtn);
string oldAction = "<form action=\"/login\" method=\"post\">";
string newAction = "<form action=\"https://abcd.com.au/login?orig_req_url=%2Fcategories/A_dfn/sdf\" method=\"post\">";
sb.Replace(oldAction, newAction);
string oldUsername = "<input id=\"login_email\" type=\"text\" name=\"user[email_address]\" class=\"textBox\" value=\"\">";
string newUserName = "<input id=\"login_email\" type=\"text\" name=\"user[email_address]\" class=\"textBox\" value=\"abc#xyz.com.au\">";
sb.Replace(oldUsername, newUserName);
string oldPass = "<input id=\"login_password\" type=\"password\" name=\"user[password]\" class=\"textBox\" value=\"\">";
string newPass = "<input id=\"login_password\" type=\"password\" name=\"user[password]\" class=\"textBox\" value=\"abc\">";
sb.Replace(oldPass,newPass);
Response.Write(sb);
This is show me expected output as I want by rendering page(Response.write(sb)). But, now I want to do same thing without redirecting to "https://abcd.com.au/login?orig_req_url=%2Fcategories/A_dfn/sdf" and want to do more stuff on this. I expect to get output of Response.Write(sb) in some buffer. Is it possible to do?
Here is example, that explains exactly what I want to do.
I am looking for an product's qty say name : Screw 15mm, this resides in page https://abcd.com.au/%2Fcategories/A_dfn/sdf.
So, I am requesting this url first, but as need login to access that page, its redirecting me to login page, filling username and password, pressing login button by using javascript,and then redirected to Originally Requested page. And on this page I want to find for that product, and return information to my web app.
All this I want to do without showing to user.
I just want to show retrieved information.
Thanks.
What you are looking for is a persisted session. Your approach towards this problem is incorrect. You are triggering the submit on the client-side. What you are trying to achieve should be done on the server-side.
The key to your scenario is to persist (store) the session & cookies set by the login page; then before your next request for the product info, inject the credential into the requesting webRequest.
Use the WebRequest object to load the login page.
Store any info (cookies) sent by the login page Response header.
create a new WebRequest object with the provided Response header, inject in userid/password.
Store any credentials returned by the Response.
Proceed to request for the quote info.
There is no generic way to do this without knowing the website you are trying to screen-scrap from. But the general step is as above. Basically, you need to create a custom class for this.
Also, you need HTMLAgilityPack to parse the HTML nodes. It is the correct method.
EDIT: Added my codes. Just so happen that I've created this class before sometime ago. So, you're in luck. However, you will need HTMLAgilityPack installed & referenced to use it. You can download HAP at: http://htmlagilitypack.codeplex.com/ If you want to do any serious screen-scraping, HAP is the de-facto standard.
Public Class clsBrowserSession
'=================================================================================================================================
'This is a special Browser Post class
' Instead of just POST to a URL as per the clsWeb.fnsPostResponse()
' clsBrowserSession allows us to LOAD a page first, persist all the cookies and variables, and then only POST to the target URL.
' The reason is that some program will drop (lets say) a SessionID as an input when you first load the page.
' and when you post, without the SessionID (variable), it will reject the POST. Thus clsBrowserSession can solve this problem.
'=================================================================================================================================
' USAGE:
' Dim voBrowserSession As New clsBrowserSession
' voBrowserSession.sbLoadPage("https://xxx.yyy.net.my/publicncdenq/index.htm")
' voBrowserSession.proFormElements("UserID") = "myID"
' voBrowserSession.proFormElements("Password") = "myPassword"
' Dim vsResponseHTML As String = voBrowserSession.Post("https://xxx.yyy.net.my/publicncdenq/index.htm")
Private vbIsPostingInProgress As Boolean
Public voCookies As System.Net.CookieCollection
Public proHTMLDoc As HtmlAgilityPack.HtmlDocument
Public proFormElements As clsFormElementCollection
Public Sub sbLoadPage(pvsURL As String)
vbIsPostingInProgress = False
fnoCreateWebRequestObject().Load(pvsURL)
End Sub
Public Function Post(pvsURL As String) As String
vbIsPostingInProgress = True
fnoCreateWebRequestObject().Load(pvsURL, "POST")
Return proHTMLDoc.DocumentNode.InnerHtml
End Function
Private Function fnoCreateWebRequestObject() As HtmlAgilityPack.HtmlWeb
Dim voWeb As New HtmlAgilityPack.HtmlWeb
voWeb.UseCookies = True
voWeb.PreRequest = New HtmlAgilityPack.HtmlWeb.PreRequestHandler(AddressOf event_OnPreRequest)
voWeb.PostResponse = New HtmlAgilityPack.HtmlWeb.PostResponseHandler(AddressOf event_OnAfterResponse)
voWeb.PreHandleDocument = New HtmlAgilityPack.HtmlWeb.PreHandleDocumentHandler(AddressOf event_OnPreHandleDocument)
Return voWeb
End Function
Private Sub sbAddPostDataTo(pvoRequest As Net.HttpWebRequest)
Dim vsPayload As String = proFormElements.fnsAssemblePostPayload()
Dim vabyteBuffer As Byte() = Text.Encoding.UTF8.GetBytes(vsPayload.ToCharArray())
pvoRequest.ContentLength = vabyteBuffer.Length
pvoRequest.ContentType = "application/x-www-form-urlencoded"
pvoRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.97 Safari/537.11"
pvoRequest.GetRequestStream().Write(vabyteBuffer, 0, vabyteBuffer.Length)
End Sub
Private Sub sbAddvoCookiesTo(pvoRequest As Net.HttpWebRequest)
If (Not IsNothing(voCookies)) Then
If voCookies.Count > 0 Then pvoRequest.CookieContainer.Add(voCookies)
End If
End Sub
Private Sub sbSaveCookiesFrom(pvoResponse As Net.HttpWebResponse)
If pvoResponse.Cookies.Count > 0 Then
If IsNothing(voCookies) Then voCookies = New Net.CookieCollection
voCookies.Add(pvoResponse.Cookies)
End If
End Sub
Private Sub sbSaveHtmlDocument(pvoHTMLDocument As HtmlAgilityPack.HtmlDocument)
proHTMLDoc = pvoHTMLDocument
proFormElements = New clsFormElementCollection(proHTMLDoc)
End Sub
Protected Function event_OnPreRequest(pvoRequest As Net.HttpWebRequest) As Boolean
sbAddvoCookiesTo(pvoRequest)
If vbIsPostingInProgress Then sbAddPostDataTo(pvoRequest)
Return True
End Function
Protected Sub event_OnAfterResponse(pvoRequest As System.Net.HttpWebRequest, pvoResponse As Net.HttpWebResponse)
sbSaveCookiesFrom(pvoResponse)
End Sub
Protected Sub event_OnPreHandleDocument(pvoHTMLDocument As HtmlAgilityPack.HtmlDocument)
sbSaveHtmlDocument(pvoHTMLDocument)
End Sub
'-----------------------------------------------------------------------------------------------------
'Form Elements class
' Note: This element class will only capture (any) INPUT elements only, which should be enough
' for most cases. It can be easily modified to add other SELECT, TEXTAREA, etc voInputs
'-----------------------------------------------------------------------------------------------------
Public Class clsFormElementCollection
Inherits Dictionary(Of String, String)
Public Sub New(htmlDoc As HtmlAgilityPack.HtmlDocument)
Dim voInputs As Collections.Generic.IEnumerable(Of HtmlAgilityPack.HtmlNode) = htmlDoc.DocumentNode.Descendants("input")
For Each voInput As HtmlAgilityPack.HtmlNode In voInputs
Dim vsName = voInput.GetAttributeValue("name", "undefined")
Dim vsValue = voInput.GetAttributeValue("value", "")
If vsName <> "undefined" Then Add(vsName, vsValue)
Next
End Sub
Public Function fnsAssemblePostPayload() As String
Dim sb As New Text.StringBuilder
For Each voKeyValuePair In Me
Dim vsValue = System.Web.HttpUtility.UrlEncode(voKeyValuePair.Value)
sb.Append("&" & voKeyValuePair.Key & "=" & vsValue)
Next
Return sb.ToString.Substring(1)
End Function
End Class
End Class
Just make the above into a class object and instantiate it. The usage example is in the comment. You want the vsResponseHTML string.
I am using the below code to get the Title and description of the youtube video embeded in my asp.net application. I am able to see the Title, but not description.
I use Atomfeed to do this...
Problem is i get the Description as "Google.GData.Client.AtomTextConstruct" for all my videos.
Private Function GetTitle(ByVal myFeed As AtomFeed) As String
Dim strTitle As String = ""
For Each entry As AtomEntry In myFeed.Entries
strTitle = entry.Title.Text
Next
Return strTitle
End Function
Private Function GetDesc(ByVal myFeed As AtomFeed) As String
Dim strDesc As String = ""
For Each entry As AtomEntry In myFeed.Entries
strDesc = entry.Summary.ToString()
Next
Return strDesc
End Function
I believe that when the XML from the atom feed is parsed, that the description is not handled. Take a look at this: http://code.google.com/p/google-gdata/wiki/UnderstandingTheUnknown
But what happens with things that are not understood? They end up as
an element of the ExtensionElements collection, that is a member of
all classes inherited from AtomBase, like AtomFeed, AtomEntry,
EventEntry etc...
So, what we can do is pull out the description from the extensionelement like this:
Dim query As New FeedQuery()
Dim service As New Service()
query.Uri = New Uri("https://gdata.youtube.com/feeds/api/standardfeeds/top_rated")
Dim myFeed As AtomFeed = service.Query(query)
For Each entry In myFeed.Entries
For Each obj As Object In entry.ExtensionElements
If TypeOf obj Is XmlExtension Then
Dim xel As XElement = XElement.Parse(TryCast(obj, XmlExtension).Node.OuterXml)
If xel.Name = "{http://search.yahoo.com/mrss/}group" Then
Dim descNode = xel.Descendants("{http://search.yahoo.com/mrss/}description").FirstOrDefault()
If descNode IsNot Nothing Then
Console.WriteLine(descNode.Value)
End If
Exit For
End If
End If
Next
Next
Also, the reason why you are getting "Google.GData.Client.AtomTextConstruct" is because Summary is an object of type Google.GData.Client.AtomTextConstruct, so doing entry.Summary.ToString() is just giving you the default ToString() behavior. You would normally do Summary.Text, but this of course is blank because as I say above, it's not handled properly by the library.
For youtube, I fetch the information for each video using the Google.GData.YouTube.
Something like this returns a lot of information from the video.
Dim yv As Google.YouTube.Video
url = New Uri("http://gdata.youtube.com/feeds/api/videos/" & video.Custom)
r = New YouTubeRequest(New YouTubeRequestSettings("??", "??"))
yv = r.Retrieve(Of Video)(url)
Then it's possible to get the description with: yv.Description