2

一方向として構成された Web サービスがあります。というか、SoapDocumentMethod 属性には「OneWay」というプロパティがあります。これは true に設定されています。

クライアント要求の IP アドレスを取得しようとしています。クライアントが他のネットワークの概念の背後にある可能性があるため、正確な IP アドレスを取得できないという事実がわかりました。それは関係ありません。サービスで呼び出しを開始した人の IP アドレスが必要なので、それがクライアント マシンの上にあるフロント エンド サーバーであれば、それでかまいません。

HttpContext を使用してみましたが、うまくいかないようです。Web サービスが実行されているのと同じマシンで Web サービスをヒットすると、HttpContext が読み込まれ、IP アドレスを取得できます。ただし、Web サービスと HttpContext の外部使用は少し混乱しています。リクエストに関する情報を見つけようとすると、多くのプロパティで例外がスローされます。そのため、クライアントの IP アドレスを取得できません。サービスのトレースを有効にすると、サービスが機能し始めます。しかし、それは一時的な回避策にすぎません。これは受け入れられる解決策ではありません。

では、一方向の Web サービスを使用している場合、クライアントの IP アドレスを取得する最良の方法は何でしょうか?

私はすでにここを見てきました: http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapdocumentmethodattribute.oneway.aspx

4

1 に答える 1

1

幸いなことに、いくつかのオプションがあります。

1) パラメータとして IP アドレスを渡す --> 推奨されません。2) IP アドレスの SOAP ヘッダーを作成し、クライアントから渡します。

オプション 2 の簡単なサンプルを書きました。

まず、SoapHeader を拡張し、IP アドレスを渡すクラスを作成する必要があります。

using System.Web.Services.Protocols;

namespace SoapHeaders
{
    public class IpAddressHeader : SoapHeader
    {
        public string IpAddress;
    }
}

次に、そのヘッダーを持つ Web サービスと、それを使用する Web メソッドを定義する必要があります。

using System;
using System.IO;
using System.Web.Services.Protocols;
using System.Web.Services;
using SoapHeaders;

namespace WebService
{

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]

    public class SoapHeaderService : System.Web.Services.WebService
    {
        public IpAddressHeader IpAddressHeader;

        [WebMethod]
        [SoapDocumentMethod(OneWay = true)]
        [SoapHeader("IpAddressHeader")]
        public void LogIpAddress()
        {
            var logFile = string.Format(@"C:\Logs\{0:yyyy-MM-dd HH.mm.ss.ffff}.log", DateTime.Now);

            string ipAddress;

            if (IpAddressHeader == null || string.IsNullOrEmpty(IpAddressHeader.IpAddress))
            {
                ipAddress = "?";
            }
            else
            {
                ipAddress = IpAddressHeader.IpAddress;
            }

            File.WriteAllText(logFile, string.Format("Client Address --> {0}", ipAddress));
        }
    }
}

最後に、サービスを利用してヘッダー情報を渡すクライアントが必要です。簡単なコンソール アプリケーションを作成しましたが、実際には何でもかまいません。

using System.Net;
using ConsoleApplication.soapHeaderServices;

namespace ConsoleApplication
{
    class Program
    {

        static void Main(string[] args)
        {
            var ipAddressHeader = new IpAddressHeader();
            ipAddressHeader.IpAddress = GetIpAddress();

            var serviceClient = new SoapHeaderService();
            serviceClient.IpAddressHeaderValue = ipAddressHeader;

            serviceClient.LogIpAddress();
        }

        static string GetIpAddress()
        {
            var ipAddress = "?";
            var host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (var address in host.AddressList)
            {
                if (address.AddressFamily.ToString() != "InterNetwork")
                {
                    continue;
                }

                ipAddress = address.ToString();
                break;
            }

            return ipAddress;
        }
    }
}

このサービスをリモート テスト サービスにデプロイし、PC から呼び出しました。正常に動作します。作成されるログファイルの内容:Client Address --> 192.168.1.41

お役に立てば幸いです。

編集:以下の コードを使用しないでください。違います。してはいけないことの例として残しています。 サーバー変数は一方向操作では使用できません

元の答え。注意して使用してください:編集の上にある私の更新された回答を参照してください。

これを新しい ASP.Net Web サービス アプリケーションでスモーク テストしました。アクセスできるすべてのエンドポイントから動作します。

HttpRequest.UserHostAddress は、クライアントの IP アドレスを取得するドキュメントの方法です。それがうまくいかない場合は、根本的な原因を探します。

[WebMethod]
[SoapDocumentMethod(OneWay = true)]
public void Silent()
{
    var address = HttpContext.Current.Request.UserHostAddress;

    // Do something with address
    Trace.Write(address);
}
于 2013-10-18T15:45:31.580 に答える