Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在单向ASMX Web服务中获取客户端IP地址_C#_Web Services_Asmx_Httpcontext - Fatal编程技术网

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

C# 如何在单向ASMX Web服务中获取客户端IP地址,c#,web-services,asmx,httpcontext,C#,Web Services,Asmx,Httpcontext,我有一个配置为单向的web服务。或者更确切地说,SoapDocumentMethod属性有一个名为“单向”的属性。这是真的 我正在尝试获取客户端请求的IP地址。我得到的事实是,我不会得到确切的IP地址,因为客户端可能落后于其他网络概念。那无关紧要。我想要一个发起服务调用的人的IP地址,所以如果是某个前端服务器位于某个客户端机器之上,那就这样吧 我尝试使用HttpContext,但似乎不起作用。如果我在运行web服务的同一台机器上点击web服务,则会填充HttpContext,我可以获得IP地址。

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

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

我尝试使用HttpContext,但似乎不起作用。如果我在运行web服务的同一台机器上点击web服务,则会填充HttpContext,我可以获得IP地址。然而,我的web服务和HttpContext的任何外部使用都有点混乱。当试图查找请求的信息时,它会对许多属性抛出异常。因此,我无法获取客户端IP地址。如果启用对服务的跟踪,它将开始工作。但这只是暂时的解决办法。这不是一个可接受的解决方案

所以。。当您使用单向web服务时,获取客户端IP地址的最佳方法是什么

我已经看过了:

幸运的是,您有一些选择

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;
        }
    }
}
我在一个远程测试服务上部署了该服务,并从我的电脑上调用了它。工作正常。创建的日志文件的内容:客户端地址-->192.168.1.41

我希望这对你有帮助

编辑:不要使用下面的代码。这是错误的。我把它作为一个不该做的例子。 服务器变量在单向操作中不可用

原始答案。注意使用:查看编辑上方的更新答案

我刚刚在一个新的ASP.NETWeb服务应用程序上进行了测试。从我可以访问的每个端点开始工作

UserHostAddress是获取客户端IP地址的文档方式。如果这对你不起作用,我会寻找潜在的原因

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

    // Do something with address
    Trace.Write(address);
}

要明确的是,这是一个老式的ASP.NETWeb服务应用程序吗?是的。我需要使用.NET3.0或更早版本。至少现在是这样。答案补充道。我希望它有帮助,但如果没有,请随意发布您自己的web方法,我将查看代码。这与我正在运行的测试非常接近,我在尝试访问该属性时遇到异常。除非我在同一台计算机上点击服务。你能在这里发布你得到的错误吗?此外,我建议将错误隔离为尽可能简单的场景。Visual Studio-->新建项目-->新建ASP.Net Web服务应用程序-->复制粘贴上述方法并尝试远程命中它。以上内容与我现在正在测试的内容基本相同。这是一个新项目。就异常而言,属性Context.Request.UserHostAddress为null,我的代码因此崩溃。此外,属性Context.Request.ServerVariables由于参数异常而崩溃。无论你尝试使用什么属性访问服务变量。ServerVariables[0],ServierVariable.Count甚至引发参数异常。对不起,我以前说错了。访问UserHostAddress不会引发异常。它只是空的。更新了我的答案。新版本将起作用。剩下的唯一一件事就是决定如何派生客户端IP地址。出于某种原因,您可能希望使用公共的,而不是本地的。对于这一点,在这里寻找一些想法:好吧,这是一个替代的解决方案。如果该方法被标记为[SoapDocumentMethod(OneWay=true)],则无法实现您想要的操作。按设计,服务器变量在单向操作中不可用。我想这是你能找到的最可行的解决办法。或者,如果不需要,可以删除该属性。