1

I have an application which is published on intranet. When I debug my application, it runs smoothly. But when I published my app and my visual studio as debugger, retrieval from entity becomes null.

Object reference is not set to an instance of an object.

From this line (using app debugger from published version):

user_mstr vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);

I am using MySQL database with entity framework. Please take note that I am working on the same PC but different version, published and not.

Update:

This is returning null only when it is published and not when running on debugger. Everything is OK on debugger.

This is the connection string:

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"" 

I think it is worth mentioning that I am working on WPF.

Amirhossein Mehrvarzi
  • 18,024
  • 7
  • 45
  • 70
Mark
  • 8,046
  • 15
  • 48
  • 78
  • `strUserCD` is null? – Just code Apr 02 '15 at 05:07
  • 7
    when you publish the app where? and which variable in this line is the debugger flagging as being not set? did the database connection strings change? do the tables exist in both databases? I know you added a big bounty to attract attention, but the reason the question doesn't have an answer isn't attention, it's the lack of information necessary to provide an answer. We can't remotely debug this for you with the limited info you provided. – Claies Apr 02 '15 at 05:33
  • yes. they all exist. as I've mentioned, this is returning null only when it is published and not when running on debugger. Everything is ok on debugger. – Mark Apr 02 '15 at 06:37
  • is the environment the same when it works with debug and when it is published? – Piero Alberto Apr 02 '15 at 06:40
  • 2
    Take a look at the sql query which generated by entity framework. It will help you to understand what is wrong. Mysql data connector always makes a lot of pain. – Maris Apr 02 '15 at 06:45
  • 2
    Do you maybe have multiple web.config versions depending on debug/release? – sroes Apr 02 '15 at 06:46
  • 2
    When I've had issues like this previously I've always added tracing (logging) debugging to the app to diagnose what's happening in the Production environment - i.e. TraceLog.WriteLine("strUserCD Value: " + strUserCD.ToString()); etc etc... – OBR_EXO Apr 02 '15 at 06:47
  • What is the context's lifespan? This could be a multi-user issue. – Gert Arnold Apr 02 '15 at 06:48
  • I think it has something to do with the version? But as you can see, I'm in trial error method here. I don't really know the details or the error. Other applications I have with this method are functioning well – Mark Apr 02 '15 at 07:15
  • @PieroAlberto, yes. Same computer. – Mark Apr 02 '15 at 07:15
  • 2
    Also same IIS? Development IIS Express is running under your account, IIS may be running as IUSR, who may or may not have access to the SQL database or a resource required to connect, depending on your configuration. Is this the first and only SQL query or do you have other queries which are successfully executed in production? – Alexander Apr 02 '15 at 07:27
  • It is the whole entity that is not returning any value. – Mark Apr 02 '15 at 08:09
  • I think the only way you can solve this is by having the same experience with this. – Mark Apr 02 '15 at 08:25
  • Can you determine which element is null from that line....so have something like: if(ctx==null) { TraceLog.WriteLine("ctx is null"); } if(ctx.user_mstr==null) { TraceLog.WriteLine("ctx.user_mstr is null"); } etc... From that you can then pinpoint where the issue begins (i.e. if ctx is null then it's the link to the DB that's got the issue) – scgough Apr 02 '15 at 10:37
  • First: check, on what user it goes on prod. version and debug version. This can be problem, that debug is on your user, and publish is on server account. Second, write to log (ex. nLog) all collection from: ctx.user_mstr (ctx.user_mstr.ToList()) from both situation. – zchpit Apr 02 '15 at 19:48
  • 1
    1) Try to profile your query. 2) Check if the user has access to the database (Application Pool Identity) 3) Check if the DatabaseObject of your context is connected 5) Check if you have a different connection string in the release app/web.config (Compare Database, Server, SQL user) 6) Check if other queries are working. 7) Try to get more information (Using logging) and post those information here (Full exception including Stacktrace, information about which object is null, details of the Database object of your context). 8) Are you using code (and first migrations) or model first? – musium Apr 03 '15 at 17:35
  • Do the data in your database match the EF model…or does the table contain some invalid data? – musium Apr 03 '15 at 17:57
  • 2
    This could also be a timing issue. Typically production environments take longer to communicate with the server than it would if you were running everything locally. Local debugging may not throw errors where production would. This would be caused by threading jobs or related activity. – leigero Apr 03 '15 at 19:31
  • Could you please post the connection string? On the other hand where do you keep Database? On your local computer? Or another server? – Murat Yıldız Apr 05 '15 at 21:08
  • If ctx is null, I should know it by debugging time. The error clearly states that it is indeed null. What I want to know is how come it is null in production? @leigero, can you elaborate more about the threading? – Mark Apr 06 '15 at 01:22
  • Have you tried to connect a remote debug session after the app has been deployed to the PC? – BMac Apr 07 '15 at 09:55
  • Have you given a thought to Account Permissions of the account in the connection string, make sure it has dbo.Owner of the Databases it's trying to connect to. – Heberda Apr 07 '15 at 12:53
  • clean the solution and run it in release mode from the IDE. or publish locally to IIS and attach the debugger. can I have the bounty? – Glenn Ferrie Apr 08 '15 at 15:31
  • How are you creating object ctx? Is it passed through constructor injection? – wonderbell Apr 08 '15 at 17:17
  • Please check following answer: http://stackoverflow.com/a/29523239/1217130 – Raishul Apr 08 '15 at 19:10
  • 1
    All the answers below are purely speculative because the question doesn't provide enough information to setup the original scenario or properly diagnose the issue. – jamesSampica Apr 08 '15 at 23:55

4 Answers4

10

Step Zero: More Exception Information!

Here is a fiddle that demonstrates a quick and dirty way to get more information from your exception message.

Create the following method. It recursively gathers relevant information from the Exception and all of its InnerException children.

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

Next, wrap your code in the following try-catch block.

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

This will give you more than the generic NullReferenceException message. With more information, you might not need anymore steps.

Possible Extra Steps

Step One, what is null?

You already know what a NullReferenceException means. You're trying to access a member on a type whose value is null. To troubleshoot, you need to determine which value is null, then you need to determine why it is null.

Here is a Fiddle that narrows down what is null. From that Fiddle, you can see that it's either the ctx that's null or the first item in the List<user_mstr> that is null (just pretend that a List is a DbSet).

Here's the code from the 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();
    }
}

And here is the output.

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.

Step Two: what is really null?

From step one, we know that either the ctx or the first item in the List<user_mstr> is null (where the List is just like a DbSet). Now we need to narrow further. One way to do that is to change your code to this:

user_mstr vwUser = null;
if(ctx != null)
{
    vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD);
}

If you still receive the NullReferenceException, then you know that the problematic null value is the first item in the List<user_mstr>. If you don't receive that exception, then you know that the problem is a null ctx.

Step Three, if the ctx is null.

Try hard-coding your connection string. Here is one way to do that.

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

Questions

  1. What version of Entity Framework are you using? The dev.mysql.com site has separate chapters about the MySQL Connector for .NET development: Chapter 9 EF 5 Support and Chapter 10 EF 6 Support.

  2. What version of .NET are you using? Check that you're using the same .NET version for both your debug and release. You'll want at least the 4.0 version.

  3. Does your release /bin contain MySql.Data.Entity.dll? If it doesn't then copy-paste it in there (and MySql.Web.dll if necessary.) There have been bugs along these lines with MySql in the Entity Framework.

  4. Are the release and debug builds using the same database?

  5. Are you using an app.config transformation? This probably isn't the case, because you're using WPF and app.config transformations do not come out-of-the-box like web.config transformations do.

  6. Are you using a web.config transformation? If you're publishing as a WPF Browser Application, then a web.config file would be appropriate, and web.config transformations can change the connection string.

  7. Have you rebuilt (clean then build) your release? You might want to go further and manually delete the /bin and /obj before your next build.

Notes

As others have mentioned, you really need more information.

  • Binkes ideas of throwing the InnerException is good.
  • Writing to a log would help.

See Also

MySQL with Entity Framework - what am I doing wrong?

Entity Framework Code First + MySQL... NullReferenceException

Community
  • 1
  • 1
Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
  • This answer may lead to the real answer. Thanks @Shaun Luttin – Mark Apr 09 '15 at 03:16
  • I can't check this right now cause I'm on a vacation. – Mark Apr 09 '15 at 03:17
  • @ChristianMark, This is a great post but I answered your question keeping in mind that you don't need to modify your existing code to figure out the cause. – Raishul Apr 09 '15 at 14:40
  • Yes Raishul, I found out that I have version incompatibility. For my PC itself I have version 5.X while on my dev environment I have 6.X. Thanks Shaun – Mark Apr 10 '15 at 03:57
  • 1
    That exception details builder doesn't provide much better than ToString() provides. I've never seen *any* exception have *anything* in the Data property. And you get all the rest in the standard ToString() output. –  Apr 10 '15 at 13:59
  • @Will Good point. The exception details doesn't seem to provide much more than using `ToString()` does and the `Data` property doesn't provide much of use if anything. At best using the exception details method provides readability. https://dotnetfiddle.net/wTNO6f – Shaun Luttin Apr 10 '15 at 16:14
  • I used to have a similar method, but then I was like "wait, ToString() gives everything I need (if it's available--I'm looking at you FileNotFoundException) without having to lug this other method around everywhere!" –  Apr 10 '15 at 16:18
2

In addition to the other good ideas.
You say published. I have seen similar issues with the way the config file gets copied. Did the publish process copy the .config OR due to publish process now needs a WEB.CONFIG not app.config file ?

In other words the app in it new location isnt accessing the config file as you suspect and isnt finding the connection string to the original Db.

phil soady
  • 11,043
  • 5
  • 50
  • 95
  • He's using WPF, so it's unlikely that a web.config would be appropriate, unless he's hosting WPF in IIS as a browser application. Hmm. https://msdn.microsoft.com/en-us/library/aa970060%28v=vs.110%29.aspx – Shaun Luttin Apr 09 '15 at 02:09
1

For anyone to actually answer this you need to provide some more information like a stacktrace or the actual error. The NullReferenceException should have an inner exception, and that is the key to know what is wrong in your published application. Add a logging framework like Log4net or another logging framework to your project. If you do this, you will most likely get the underlying error and stacktrace by just logging the exception. This will also help you alot, further down the line when unexpected errors occur.

You can always try the following to get some more information about what might be wrong:

Wrap your code in a try-catch and throw the InnerException

try { 
    vwUser = ctx.user_mstr.FirstOrDefault(x => x.user_cd == strUserCD); 
}
catch(Exception ex) 
{ 
    throw ex.InnerException; 
}
  • Check your published connectionstring so that you don't have a transorm config that modifies your connectionstring to something unexpected.

  • Make sure that your IUSR and ApplicationPoolIdentity have the right permissions.

  • Remove your bin and obj folders from your project, clean the solution and rebuild it. Try to publish a debug version and se if it's working as expected. Publish a release version and se if it works.

Binke
  • 897
  • 8
  • 25
1

You may perform following tasks to figure out:

  1. To find what is happening behind the scene, verify the query translated by
    entity framework by implemententing free profiler by how to guideline from here : http://4rapiddev.com/mysql/free-mysql-profiler-similar-to-microsoft-sql-server-profiler-logmonitor/

  2. Check the value for strUserCD variable

  3. Execute the returned query manually in MySQL

  4. If no row is being returned please change the logic how you are assinging strUserCD
    variable.

  5. Publish the web application and observe any exception is being returned or not.

Raishul
  • 146
  • 2
  • 6