cannot get clients ip address in web.api

2.1k views Asked by At

I'm building a Web.Api (mvc & web.api) and try to get the clients ip adress with this code..

[System.Web.Http.HttpPut]
public HttpResponseMessage Update([FromBody] BookInformation bookStatus)
{
  // Stuff...

  // Retrieve clients IP#
  var clientIp = (System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.UserHostAddress
}

But I get this error:

'System.Web.HttpRequestBase' does not contain a definition for 'Properties' and no extension method 'Properties' accepting a first argument of type 'System.Web.HttpRequestBase' could be found (are you missing a using directive or an assembly reference?)

What am I missing here?

2

There are 2 answers

1
Nkosi On

According to the exception message it is saying that Request is of type System.Web.HttpRequestBase and Properties does not exist, which would be accurate for that class. This looks like you are mixing MVC and WebApi Controllers.

the System.Web.HttpRequestBase Request you are referencing is part of MVC Controller.Request but your method structure looks like it is suppose to be part of a Web Api System.Web.Http.ApiController which has a System.Web.Http.HttpRequestMessage Request property as well.

Make sure you are inheriting from the correct controller.

public class BooksController : System.Web.Http.ApiController {...}

I've used this extension helper to get the client ip with an ApiController

static class HttpRequestMessageExtensions {
    private const string HttpContext = "MS_HttpContext";
    private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
    private const string OwinContext = "MS_OwinContext";

    public static string GetClientIpString(this HttpRequestMessage request) {
        //Web-hosting
        if (request.Properties.ContainsKey(HttpContext)) {
            dynamic ctx = request.Properties[HttpContext];
            if (ctx != null) {
                return ctx.Request.UserHostAddress;
            }
        }
        //Self-hosting
        if (request.Properties.ContainsKey(RemoteEndpointMessage)) {
            dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage];
            if (remoteEndpoint != null) {
                return remoteEndpoint.Address;
            }
        }
        //Owin-hosting
        if (request.Properties.ContainsKey(OwinContext)) {
            dynamic ctx = request.Properties[OwinContext];
            if (ctx != null) {
                return ctx.Request.RemoteIpAddress;
            }
        }
        if (System.Web.HttpContext.Current != null) {
            return System.Web.HttpContext.Current.Request.UserHostAddress;
        }
        // Always return all zeroes for any failure
        return "0.0.0.0";
    }
}

And used like this

public class BooksController : System.Web.Http.ApiController {

    [System.Web.Http.HttpPut]
    public HttpResponseMessage Update([FromBody] BookInformation bookStatus) {
      // Stuff...

      // Retrieve clients IP#
      var clientIp = Request.GetClientIpString();
    }
}
0
Morteza Mousavi On

you should add reference System.ServiceModel and System.ServiceModel.channel