我在Silverlight中使用ASP.NET(.asmx)Web服务。由于无法在Silverlight中找到客户端IP地址,因此我必须在服务端登录。 这些是我尝试过的一些方法:
Request.ServerVariables("REMOTE_HOST")
HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]
HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
Request.UserHostAddress()
Request.UserHostName()
string strHostName = Dns.GetHostName();
string clientIPAddress = Dns.GetHostAddresses(strHostName).GetValue(0).ToString();
以上所有方法在我的本地系统上运行正常,但是当我在生产服务器上发布服务时,它会开始出错,
错误:对象引用未设置为对象的实例。堆栈跟踪:
at System.Web.Hosting.ISAPIWorkerRequestInProc.GetAdditionalServerVar(Int32 index)
at System.Web.Hosting.ISAPIWorkerRequestInProc.GetServerVariable(String name)
at System.Web.Hosting.ISAPIWorkerRequest.GetRemoteAddress()
在System.Web.HttpRequest.get_UserHostAddress()
答案 0 :(得分:5)
您应该尝试找出NullReferenceException
的确切来源。更改代码以了解某些内容可以返回null。例如,在
HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]
HttpContext.Current
可能会返回null,或.Request
可能返回null,或.ServerVariables["REMOTE_ADDR"]
可能返回null。另外,在
string clientIPAddress = System.Net.Dns.GetHostAddresses(strHostName).GetValue(0).ToString();
GetHostAddresses(strHostName)
可能返回null,或.GetValue(0)
可能返回null。
如果方法或属性可以返回null,那么在解除引用之前应该检查null。例如,
IPAddress[] hostAddresses = System.Net.Dns.GetHostAddresses(strHostName);
string clientIPAddress;
if (hostAddresses != null)
{
object value = hostAddresses.GetValue(0);
if (value != null)
{
clientIPAddress = value.ToString();
}
}
P.S。我不知道你为什么要使用GetValue(0)
。请改用hostAddresses[0]
。
答案 1 :(得分:2)
如果您在System.Web.Hosting.ISAPIWorkerRequestInProc.GetAdditionalServerVar代码中使用Reflector查看,那就是我们所看到的:
private string GetAdditionalServerVar(int index)
{
if (this._additionalServerVars == null)
{
this.GetAdditionalServerVariables();
}
return this._additionalServerVars[index - 12];
}
我看到为什么会引发NullReferenceException的两个原因:
1)_additionalServerVars成员存在多线程问题。我不认为这可能发生,因为A)我不明白为什么在测试期间服务器上会有很大的负载,而且B)ISAPIWorkerRequestInProc实例可能与一个线程有关。
2)您的服务器不是最新的,生产中的代码与我在机器上看到的代码不同。
所以我要做的就是检查服务器,确保它与.NET Framework dll保持同步。