Category Archives: WCF

ASP.NET でクライアントの IP アドレスを取得する

ASP.NET MVC や Web API で、クライアントの IP アドレスを取得する方法をまとめておきます。プロキシサーバーなどを経由して Web サーバーに接続された場合、HTTP ヘッダーの X-Forwarded-For から取得する必要があります。

ASP.NET MVC

サーバー環境変数から取得しているため、HTTP_X_FORWARDED_FOR がキーとなります。

public ActionResult Index()
{
    var clientIp = "";
    var xForwardedFor = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    if (String.IsNullOrEmpty(xForwardedFor) == false)
    {
        clientIp = xForwardedFor.Split(',').GetValue(0).ToString().Trim();
    }
    else
    {
        clientIp = Request.UserHostAddress;
    }

    if (clientIp != "::1"/*localhost*/)
    {
        clientIp = clientIp.Split(':').GetValue(0).ToString().Trim();
    }

    ViewBag.Message = clientIp;
    return View();
}

ASP.NET Web API

HTTP ヘッダーの X-Forwarded-For から取得します。OWIN を使っている場合は、MS_HttpContext ではなく、MS_OwinContext の RemoteIpAddress から取得します。

public string Get()
{
    IEnumerable<string> headerValues;
    var clientIp = "";
    if (ControllerContext.Request.Headers.TryGetValues("X-Forwarded-For", out headerValues) == true)
    {
        var xForwardedFor = headerValues.FirstOrDefault();
        clientIp = xForwardedFor.Split(',').GetValue(0).ToString().Trim();
    }
    else
    {
        if (ControllerContext.Request.Properties.ContainsKey("MS_HttpContext"))
        {
            clientIp = ((HttpContextWrapper)ControllerContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress;
        }
    }

    if (clientIp != "::1"/*localhost*/)
    {
        clientIp = clientIp.Split(':').GetValue(0).ToString().Trim();
    }
    return clientIp;
}

WCF

おまけです。WCF の場合は、HttpRequestMessageProperty から HTTP ヘッダーの情報を取得できます。

public string GetData(int value)
{
    var clientIp = "";
    var properties = OperationContext.Current.IncomingMessageProperties;
    var httpRequestMessage = properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
    if (httpRequestMessage.Headers["X-Forwarded-For"] != null)
    {
        var xForwardedFor = httpRequestMessage.Headers["X-Forwarded-For"];
        clientIp = xForwardedFor.Split(',').GetValue(0).ToString().Trim();
    }
    else
    {
        var remoteEndpointMessage = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
        clientIp = remoteEndpointMessage.Address;
    }

    if (clientIp != "::1"/*localhost*/)
    {
        clientIp = clientIp.Split(':').GetValue(0).ToString().Trim();
    }
    return clientIp;
}

以上です。

Windows Phone 8.1 では WCF がサポートされていなかった

タイトルの通りなのですが、Windows Phone 8.1 では、WCF(System.ServiceModel 名前空間)に非対応でした。ServiceContract などを使おうとしても、コンパイルエラーとなってしまいます。

wcf

Silverlight のサブセットである Windows Phone 7.5 や 8.0 では、WCF の通信が可能でした。Universal Windows App では、ストアと電話の API は 9 割の互換性を持つと言われていますが、WCF が非互換の1割に含まれていたとは。

すでに ASP.NET Web API などでサービスを公開し、HttpClient で通信するプログラミングが中心となっており、今さらモバイル向けに WCF で通信することはないと思いますが・・・