c# - 如何在单向 ASMX Web 服务中获取客户端 IP 地址

标签 c# web-services asmx httpcontext

我有一个配置为单向的 Web 服务。或者更确切地说,SoapDocumentMethod 属性有一个名为“OneWay”的属性。即设置为真。

我正在尝试获取客户端请求的 IP 地址。我知道我无法获得确切的 IP 地址,因为客户端可能落后于其他网络概念。那是无关紧要的。我想要一个发起服务调用的人的 IP 地址,所以如果那是某个客户端机器上的某个前端服务器,那就这样吧。

我尝试使用 HttpContext,但这似乎不起作用。如果我在运行 web 服务的同一台机器上访问我的 web 服务,那么 HttpContext 就会被填充,我可以获得 IP 地址。但是,我的 Web 服务和 HttpContext 的任何外部使用都有些困惑。当试图找出有关请求的信息时,它会在许多属性上抛出异常。所以我无法获取客户端IP地址。如果启用服务跟踪,它就会开始工作。但这只是暂时的解决方法。这不是一个可接受的解决方案。

那么..当您拥有单向网络服务时,获取客户端 IP 地址的最佳方式是什么?

我已经看过这里了: http://msdn.microsoft.com/en-us/library/system.web.services.protocols.soapdocumentmethodattribute.oneway.aspx

最佳答案

幸运的是,您有一些选择。

1) 将 IP 地址作为参数传递 --> 不推荐。 2) 为 IP 地址创建一个 SOAP header 并从客户端传递它

我给你写了一个选项 2 的快速示例。

首先,您需要扩展 SoapHeader 并创建一个类来传递 IP 地址。

using System.Web.Services.Protocols;

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

接下来,您需要使用该 header 定义一个 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));
        }
    }
}

最后,您需要一个客户端来消费服务并传递 header 信息。我只是做了一个快速的控制台应用程序,但它可以是任何东西,真的:

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);
}

关于c# - 如何在单向 ASMX Web 服务中获取客户端 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19453559/

相关文章:

c# - 等待来自 SendGrid 的 API 返回代码时应用程序卡住

c# - 在 TreeView 列表中隐藏节点。在 C#

c# - 使用 GetHashCode 获取 "secure"用户密码

java - Spring ClientInterceptor 在响应中显示空的 SOAP header

java - 同时调用 2 个 Restful Web 服务。可以用骡子吗?

asp.net - JSON 可以调用 .aspx 文件中的方法,但不能调用 .asmx(ASP.NET Web 服务)文件中的方法

asp.net - 如何在asp.net core中访问asmx服务

asp.net - ASMX Web 服务对传入请求使用错误的编码

C# GetMethod 与 GetRuntimeMethod

c# - HttpWebRequest C# 的 API 超时错误 |与 postman 和 restsharp 一起工作