1

I have a VB.NET project that uses the ASP.NET Web API, self-hosted.

I've been attempting to follow along with This link (Get the IP address of the remote host) to understand how to get the IP address of a client sending a message to my application, but every time I attempt to translate an item from the page referenced above to VB.NET, I run into errors.

I'd love to use the one-liner they referenced, below:

var host = ((dynamic)request.Properties["MS_HttpContext"]).Request.UserHostAddress;

However, that translates (using Telerik's .NET converter) to the following, which produces an error that 'Dynamic' is not a type:

Dim host = DirectCast(request.Properties("MS_HttpContext"), dynamic).Request.UserHostAddress

When using any of the other solutions in the article above, I end up stopping after getting the error that httpcontextwrapper is not defined, even after adding any references i can think of / that are mentioned on the page.

A requirement for a project I'm working on is that a request only be processed if it is from a specific IP address, and that this be handled by the application. So I'm attempting to get the IP address from this incoming request, so that it may be compared with a variable.

Community
  • 1
  • 1
schizoid04
  • 888
  • 1
  • 11
  • 27

2 Answers2

2

dynamic not exists in the vb.net

But you will get same behavior if you cast it to HttpContextWrapper instead of dynamic.

Dim host As String = DirectCast(request.Properties("MS_HttpContext"), HttpContextWrapper).
                         Request.
                         UserHostAddress

Or in little more readable style:

Dim wrapper As HttpContextWrapper = 
    DirectCast(request.Properties("MS_HttpContext"), HttpContextWrapper)

Dim host As String = wrapper.request.UserHostAddress

If you want get same behavior as dynamic - see answer of @Reza Aghaei

Fabio
  • 31,528
  • 4
  • 33
  • 72
2

You can get the IP of client this way:

Dim IP = ""
If (Request.Properties.ContainsKey("MS_HttpContext")) Then
    IP = DirectCast(Request.Properties("MS_HttpContext"), HttpContextWrapper) _
            .Request.UserHostAddress
ElseIf (Request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name)) Then
    Dim p = DirectCast(Request.Properties(RemoteEndpointMessageProperty.Name),  _
        RemoteEndpointMessageProperty)
    IP = p.Address
End If

You should add reference to System.Web and System.ServiceModel, also Imports Imports System.ServiceModel.Channels.

Note

To use dynamic way, you should first add Option Strict Off as first line of the code file, then:

Dim ip = Request.Properties("MS_HttpContext").Request.UserHostAddress()
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
  • When trying the first method, I get an error on the httpcontextwrapper section saying that it's not defined. I'm able to build using the second example, the 'dynamic' way, but when the function is called, it gives me a 'given key was not present in dictionary' error message on the line containing that code – schizoid04 Sep 25 '16 at 08:30
  • I suspect for some reason that property might not be returning a value when I call it for some reason.... I added the following If statement, so that the call wouldn't throw an exception. Now, however, it just evaluates this if statement as false and continues on. Does it matter that I'm testing this from localhost? If request.Properties.Keys.Contains("MS_HttpContext") Then – schizoid04 Sep 25 '16 at 08:52
  • *1)* I didn't add namespace but you can also use `System.Web.HttpContextWrapper` *2)* I'm also using localhost without any problem. – Reza Aghaei Sep 25 '16 at 10:50
  • When I do this, I get an error on the same word saying System.Web.HttpContextWrapper is not a defined type.... At this point I'm puzzled, because this type seems to be available for most other users.... – schizoid04 Sep 25 '16 at 15:54
  • 1
    Do you have `System.Web.dll` in project references? I created a VB WebAPI project using Visual Studio 2013 and didn't add any references myself, but `System.Web.HttpContextWrapper` belongs to `System.Web` dll. – Reza Aghaei Sep 25 '16 at 16:02
  • Ah. It would seem I had a few sub-components of system.web, such as system.web.http, etc; but not system.web itself. I had tried using an Imports statement for it but it didn't seem to make a difference then. I just now caught the 'project reference' bit and added it as a reference. I'm now able to build with this method, but when called, I get the 'Given key was not present in the dictionary' error I was receiving when attempting it the other way. – schizoid04 Sep 25 '16 at 16:07
  • 1
    Oops, I was testing on IIS not self-hosting. I edited the answer for support self-hosted too. – Reza Aghaei Sep 26 '16 at 00:11
  • Let me know if you have any question about the answer. I used a console application to host the web api and tested the solution this way. – Reza Aghaei Sep 26 '16 at 18:29
  • 1
    This worked for me in a console. I haven't responded yet so far because I've been stuck on something else... I tried moving this into a windows service that had the same setup, and it worked for me once, and then kept throwing null reference errors any time any of the methods in the apicontroller were called. But it doesn't have anything to do with this question so i think i'll have to post that as a separate question / issue on here D: – schizoid04 Sep 26 '16 at 21:37
  • What's the reason for hosting a WebAPI in Windows Service? What kind of applications the API is supposed to serve? – Reza Aghaei Sep 26 '16 at 21:40
  • The application needs to accept an incoming API, then connect to a separate application via an API. Wanted a windows service so it could load automatically w/ windows, and would always be running vs a console app having to be manually run each time. Will facilitate an integration between two separate applications who's API's are incompatible – schizoid04 Sep 26 '16 at 22:21
  • I prefer using a console application. You can simply put the console application in startup in a way that starts before login, like windows services. To do so, you can use `Task Scheduler→Create Bsic Task` Follow the wizard and in `Trigger` choose `When the computer starts`. – Reza Aghaei Sep 26 '16 at 22:33
  • Is there any way to get that scheduled task creation to happen automatically as part of an installation via an installshield wizard? I am fairly partial to the simple setup from the installshield project... – schizoid04 Sep 26 '16 at 23:57
  • 1
    Solution to that problem, to get things working as a windows service was found here: http://stackoverflow.com/questions/24805600/hosting-webapi-in-windows-service-crash-by-first-attemp It now functions, including the IP bit. Thanks for all the help! – schizoid04 Sep 27 '16 at 00:32
  • About putting in start-up, yes there is multiple ways, for example [this one](http://stackoverflow.com/questions/5394098/how-to-make-an-exe-start-at-the-windows-startup) and in general I'd prefer using console. Anyway your problem is solved and that's the good news :) – Reza Aghaei Sep 27 '16 at 05:25
  • Let me know if you have more question about the answer :) – Reza Aghaei Sep 27 '16 at 16:49