发布应用程序时实体返回 null
Entity is returning null when application is published
我有一个在内网上发布的应用程序。当我调试我的应用程序时,它运行顺利。但是当我发布我的应用程序和我的 visual studio 作为调试器时,从实体中检索变成 null
.
Object reference is not set to an instance of an object.
从这一行开始(使用已发布版本的应用程序调试器):
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
我在 entity framework 中使用 MySQL 数据库。请注意,我在同一台 PC 上工作,但版本不同,已发布和未发布。
更新:
这仅在发布时返回 null
,在调试器上 运行 时不返回。调试器一切正常。
这是连接字符串:
connectionString="metadata=res://*/DataAccess.entityName.csdl|res://*/DataAccess.entityName.ssdl|res://*/DataAccess.entityName.msl;provider=MySql.Data.MySqlClient;provider connection string="server=servername;user id=username;password=password;persistsecurityinfo=True;Convert Zero Datetime=True;database=default_db""
我觉得值得一提的是我在做WPF
要让任何人真正回答这个问题,您需要提供更多信息,例如堆栈跟踪或实际错误。 NullReferenceException 应该有一个 内部异常 ,这是了解已发布应用程序中错误的关键。向您的项目添加一个日志框架,如 Log4net 或其他日志框架。如果你这样做,你很可能会通过记录异常来获得底层错误和堆栈跟踪。当发生意外错误时,这也将对您有很大帮助。
您可以随时尝试以下操作以获取有关可能出现的问题的更多信息:
将您的代码包装在 try-catch 中并抛出 InnerException
try {
vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch(Exception ex)
{
throw ex.InnerException;
}
检查您发布的连接字符串,确保您没有
将您的连接字符串修改为某些东西的transorm配置
出乎意料。
确保您的 IUSR 和 ApplicationPoolIdentity 具有正确的
权限。
从项目中删除 bin 和 obj 文件夹,清理
解决方案并重建它。尝试发布一个 debug 版本,如果
它按预期工作。发布一个 release 版本并确定它
有效。
零步:更多异常信息!
Here is a fiddle that demonstrates 一种从异常消息中获取更多信息的快速而肮脏的方法。
创建以下方法。它递归地从 Exception
及其所有 InnerException
子级收集相关信息。
public string ExceptionDetails(StringBuilder b, Exception e)
{
if (e != null)
{
b.AppendLine("\n\n-----");
b.AppendLine("Data:".PadRight(20) + e.Data);
b.AppendLine("Message:".PadRight(20) + e.Message);
b.AppendLine("StackTrace:".PadRight(17) + e.StackTrace);
b.AppendLine("TargetSite:".PadRight(20) + e.TargetSite.ToString());
b.AppendLine("-----");
ExceptionDetails(b, e.InnerException);
}
return b.ToString();
}
接下来,将您的代码包装在以下 try-catch 块中。
try
{
user_mstr vwUser =
ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (Exception e)
{
var builder = new StringBuilder();
var details = ExceptionDetails(builder, e);
throw new Exception(details);
}
这会给您带来比一般 NullReferenceException
信息更多的信息。有了更多信息,您可能不再需要其他步骤了。
可能的额外步骤
第一步,什么是null?
您已经知道 NullReferenceException 的含义。您正在尝试访问值为 null 的类型的成员。要排除故障,您需要确定哪个值为空,然后您需要确定它为什么为空。
Here is a Fiddle that narrows down what is null。从 Fiddle 中,您可以看到 ctx
为空,或者 List<user_mstr>
中的第一项为空(假设 List
是 DbSet
).
这是来自 Fiddle.
的代码
using System;
using System.Collections.Generic;
using System.Linq;
public class user_mstr
{
public string user_cd;
}
public class FakeContext
{
public List<user_mstr> user_mstr;
}
public class Program
{
private static string strUserCD = "foo";
private static void FirstUserAsNull()
{
try
{
Console.WriteLine("FirstUserAsNull");
FakeContext ctx = new FakeContext();
ctx.user_mstr = new List<user_mstr>() { null, new user_mstr(), new user_mstr() };
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentNullException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
}
}
private static void UserListAsNull()
{
try
{
Console.WriteLine("UserListAsNull");
FakeContext ctx = new FakeContext();
ctx.user_mstr = null;
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentNullException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
}
}
private static void CtxAsNull()
{
try
{
Console.WriteLine("CtxAsNull");
FakeContext ctx = null;
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
}
}
public static void Main()
{
CtxAsNull();
UserListAsNull();
FirstUserAsNull();
}
}
这是输出。
CtxAsNull
Object reference not set to an instance of an object.
UserListAsNull
Value cannot be null.
Parameter name: source
FirstUserAsNull
Object reference not set to an instance of an object.
第二步:什么是真正的 null?
从第一步,我们知道 ctx
或 List<user_mstr>
中的第一项为空(其中 List
就像 DbSet
) .现在我们需要进一步缩小范围。一种方法是将您的代码更改为:
user_mstr vwUser = null;
if(ctx != null)
{
vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
如果您仍然收到 NullReferenceException
,那么您就知道有问题的空值是 List<user_mstr>
中的第一项。如果您没有收到该异常,那么您就知道问题是 null ctx
.
第三步,如果 ctx
为空。
尝试对连接字符串进行硬编码。这是一种方法。
var providerName = "MySql.Data.MySqlClient";
var builder = new StringBuilder();
builder.Append("server=servername;");
builder.Append("user id=username;");
builder.Append("password=password;");
builder.Append("persistsecurityinfo=True;");
builder.Append("Convert Zero Datetime=True;");
builder.Append("database=default_db");
var providerString = builder.ToString();
var entityBuilder = new EntityConnectionStringBuilder();
entityBuilder.Provider = providerName;
entityBuilder.ProviderConnectionString = providerString;
entityBuilder.Metadata = @"res://*/DataAccess.entityName.csdl|
res://*/DataAccess.entityName.ssdl|
res://*/DataAccess.entityName.msl";
using (var conn = new EntityConnection(entityBuilder.ToString()))
{
conn.Open();
// do something
conn.Close();
}
问题
您使用的 Entity Framework 是什么版本? dev.mysql.com 站点有单独的章节介绍 MySQL 连接器对于 .NET 开发:Chapter 9 EF 5 Support and Chapter 10 EF 6 Support.
您使用的是什么版本的 .NET? 检查您使用的调试和发布版本是否相同。您至少需要 4.0 版本。
您的版本/bin 是否包含 MySql.Data.Entity.dll? 如果没有,则将其复制粘贴到那里(并且 MySql.Web.dll 如有必要。)Entity Framework.
中的 MySql 存在错误
发布版和调试版是否使用相同的数据库?
您是否在使用 app.config 转换? 这可能不是这种情况,因为您使用的是 WPF 和 app.config transformations do not come out-of-the-box 就像 web.config 转换一样。
您是否使用 web.config 转换? 如果您发布为 WPF Browser Application, then a web.config file would be appropriate, and web.config transformations 可以更改连接字符串。
您是否重建(清理然后构建)您的版本?您可能想要更进一步并手动删除 /bin
和 /obj
在你的下一个构建之前。
备注
正如其他人所提到的,您确实需要更多信息。
- 宾克斯抛出的想法
InnerException
很好。
- 写入日志会有所帮助。
另请参阅
MySQL with Entity Framework - what am I doing wrong?
Entity Framework Code First + MySQL... NullReferenceException
您可以执行以下任务来弄清楚:
要了解幕后发生的事情,请验证由
翻译的查询
entity framework 通过实施 free profiler 通过如何从这里指导:
http://4rapiddev.com/mysql/free-mysql-profiler-similar-to-microsoft-sql-server-profiler-logmonitor/
检查 strUserCD 变量的值
在MySQL
中手动执行返回的查询
如果没有返回任何行,请更改您分配 strUserCD 的逻辑
变量.
发布 Web 应用程序并观察是否返回任何异常。
除此之外的其他好点子。
你说发表。我在复制配置文件的方式上看到了类似的问题。
发布过程是否复制了 .config 或由于发布过程现在需要 WEB.CONFIG 而不是 app.config 文件?
换句话说,新位置中的应用程序没有像您怀疑的那样访问配置文件,也没有找到原始 Db 的连接字符串。
我有一个在内网上发布的应用程序。当我调试我的应用程序时,它运行顺利。但是当我发布我的应用程序和我的 visual studio 作为调试器时,从实体中检索变成 null
.
Object reference is not set to an instance of an object.
从这一行开始(使用已发布版本的应用程序调试器):
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
我在 entity framework 中使用 MySQL 数据库。请注意,我在同一台 PC 上工作,但版本不同,已发布和未发布。
更新:
这仅在发布时返回 null
,在调试器上 运行 时不返回。调试器一切正常。
这是连接字符串:
connectionString="metadata=res://*/DataAccess.entityName.csdl|res://*/DataAccess.entityName.ssdl|res://*/DataAccess.entityName.msl;provider=MySql.Data.MySqlClient;provider connection string="server=servername;user id=username;password=password;persistsecurityinfo=True;Convert Zero Datetime=True;database=default_db""
我觉得值得一提的是我在做WPF
要让任何人真正回答这个问题,您需要提供更多信息,例如堆栈跟踪或实际错误。 NullReferenceException 应该有一个 内部异常 ,这是了解已发布应用程序中错误的关键。向您的项目添加一个日志框架,如 Log4net 或其他日志框架。如果你这样做,你很可能会通过记录异常来获得底层错误和堆栈跟踪。当发生意外错误时,这也将对您有很大帮助。
您可以随时尝试以下操作以获取有关可能出现的问题的更多信息:
将您的代码包装在 try-catch 中并抛出 InnerException
try {
vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch(Exception ex)
{
throw ex.InnerException;
}
检查您发布的连接字符串,确保您没有 将您的连接字符串修改为某些东西的transorm配置 出乎意料。
确保您的 IUSR 和 ApplicationPoolIdentity 具有正确的 权限。
从项目中删除 bin 和 obj 文件夹,清理 解决方案并重建它。尝试发布一个 debug 版本,如果 它按预期工作。发布一个 release 版本并确定它 有效。
零步:更多异常信息!
Here is a fiddle that demonstrates 一种从异常消息中获取更多信息的快速而肮脏的方法。
创建以下方法。它递归地从 Exception
及其所有 InnerException
子级收集相关信息。
public string ExceptionDetails(StringBuilder b, Exception e)
{
if (e != null)
{
b.AppendLine("\n\n-----");
b.AppendLine("Data:".PadRight(20) + e.Data);
b.AppendLine("Message:".PadRight(20) + e.Message);
b.AppendLine("StackTrace:".PadRight(17) + e.StackTrace);
b.AppendLine("TargetSite:".PadRight(20) + e.TargetSite.ToString());
b.AppendLine("-----");
ExceptionDetails(b, e.InnerException);
}
return b.ToString();
}
接下来,将您的代码包装在以下 try-catch 块中。
try
{
user_mstr vwUser =
ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (Exception e)
{
var builder = new StringBuilder();
var details = ExceptionDetails(builder, e);
throw new Exception(details);
}
这会给您带来比一般 NullReferenceException
信息更多的信息。有了更多信息,您可能不再需要其他步骤了。
可能的额外步骤
第一步,什么是null?
您已经知道 NullReferenceException 的含义。您正在尝试访问值为 null 的类型的成员。要排除故障,您需要确定哪个值为空,然后您需要确定它为什么为空。
Here is a Fiddle that narrows down what is null。从 Fiddle 中,您可以看到 ctx
为空,或者 List<user_mstr>
中的第一项为空(假设 List
是 DbSet
).
这是来自 Fiddle.
的代码using System;
using System.Collections.Generic;
using System.Linq;
public class user_mstr
{
public string user_cd;
}
public class FakeContext
{
public List<user_mstr> user_mstr;
}
public class Program
{
private static string strUserCD = "foo";
private static void FirstUserAsNull()
{
try
{
Console.WriteLine("FirstUserAsNull");
FakeContext ctx = new FakeContext();
ctx.user_mstr = new List<user_mstr>() { null, new user_mstr(), new user_mstr() };
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentNullException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
}
}
private static void UserListAsNull()
{
try
{
Console.WriteLine("UserListAsNull");
FakeContext ctx = new FakeContext();
ctx.user_mstr = null;
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.Message);
}
catch (ArgumentNullException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
}
}
private static void CtxAsNull()
{
try
{
Console.WriteLine("CtxAsNull");
FakeContext ctx = null;
user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
catch (NullReferenceException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
}
}
public static void Main()
{
CtxAsNull();
UserListAsNull();
FirstUserAsNull();
}
}
这是输出。
CtxAsNull
Object reference not set to an instance of an object.
UserListAsNull
Value cannot be null.
Parameter name: source
FirstUserAsNull
Object reference not set to an instance of an object.
第二步:什么是真正的 null?
从第一步,我们知道 ctx
或 List<user_mstr>
中的第一项为空(其中 List
就像 DbSet
) .现在我们需要进一步缩小范围。一种方法是将您的代码更改为:
user_mstr vwUser = null;
if(ctx != null)
{
vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}
如果您仍然收到 NullReferenceException
,那么您就知道有问题的空值是 List<user_mstr>
中的第一项。如果您没有收到该异常,那么您就知道问题是 null ctx
.
第三步,如果 ctx
为空。
尝试对连接字符串进行硬编码。这是一种方法。
var providerName = "MySql.Data.MySqlClient";
var builder = new StringBuilder();
builder.Append("server=servername;");
builder.Append("user id=username;");
builder.Append("password=password;");
builder.Append("persistsecurityinfo=True;");
builder.Append("Convert Zero Datetime=True;");
builder.Append("database=default_db");
var providerString = builder.ToString();
var entityBuilder = new EntityConnectionStringBuilder();
entityBuilder.Provider = providerName;
entityBuilder.ProviderConnectionString = providerString;
entityBuilder.Metadata = @"res://*/DataAccess.entityName.csdl|
res://*/DataAccess.entityName.ssdl|
res://*/DataAccess.entityName.msl";
using (var conn = new EntityConnection(entityBuilder.ToString()))
{
conn.Open();
// do something
conn.Close();
}
问题
您使用的 Entity Framework 是什么版本? dev.mysql.com 站点有单独的章节介绍 MySQL 连接器对于 .NET 开发:Chapter 9 EF 5 Support and Chapter 10 EF 6 Support.
您使用的是什么版本的 .NET? 检查您使用的调试和发布版本是否相同。您至少需要 4.0 版本。
您的版本/bin 是否包含 MySql.Data.Entity.dll? 如果没有,则将其复制粘贴到那里(并且 MySql.Web.dll 如有必要。)Entity Framework.
中的 MySql 存在错误
发布版和调试版是否使用相同的数据库?
您是否在使用 app.config 转换? 这可能不是这种情况,因为您使用的是 WPF 和 app.config transformations do not come out-of-the-box 就像 web.config 转换一样。
您是否使用 web.config 转换? 如果您发布为 WPF Browser Application, then a web.config file would be appropriate, and web.config transformations 可以更改连接字符串。
您是否重建(清理然后构建)您的版本?您可能想要更进一步并手动删除
/bin
和/obj
在你的下一个构建之前。
备注
正如其他人所提到的,您确实需要更多信息。
- 宾克斯抛出的想法
InnerException
很好。 - 写入日志会有所帮助。
另请参阅
MySQL with Entity Framework - what am I doing wrong?
Entity Framework Code First + MySQL... NullReferenceException
您可以执行以下任务来弄清楚:
要了解幕后发生的事情,请验证由
翻译的查询 entity framework 通过实施 free profiler 通过如何从这里指导: http://4rapiddev.com/mysql/free-mysql-profiler-similar-to-microsoft-sql-server-profiler-logmonitor/检查 strUserCD 变量的值
在MySQL
中手动执行返回的查询
如果没有返回任何行,请更改您分配 strUserCD 的逻辑
变量.发布 Web 应用程序并观察是否返回任何异常。
除此之外的其他好点子。
你说发表。我在复制配置文件的方式上看到了类似的问题。
发布过程是否复制了 .config 或由于发布过程现在需要 WEB.CONFIG 而不是 app.config 文件?
换句话说,新位置中的应用程序没有像您怀疑的那样访问配置文件,也没有找到原始 Db 的连接字符串。