1

I have the following snippet of code

Addresses addresses = new Addresses();
AddressInfo addr = addresses.GetAddressFromID(csTestSecurityToken, addrID);
addr.AddressCode = "SLGTest";
if (addr.AddressCode != "SLGTest")
    throw new Exception("Address code did not match");

The if statement is always evaluating as true and throwing the exception, even though it is quite clearly false.

Can anyone shed some light as to why this is happening?

Edited:

This code works fine

Addresses addresses = new Addresses();
AddressInfo addr = addresses.GetAddressFromID(csTestSecurityToken, addrID);
addr.AddressCode = "SLGTest";
if (addr.AddressCode != "SLGTest")
    throw new Exception("Address code did not match");

addr = addr;

I'm guessing it's disposing my object too soon?

AddressType:

public class AddressInfo
{
    public enum AddressTypes { Undefined, HomeOwner, Builder, Dealer, Shipping, Main, Billing }
    public AddressInfo() 
    {
        ID = -1;
        AddressCode = string.Empty;
        ResellerID = string.Empty;
        AddressType = AddressTypes.Undefined;
        CompanyName = string.Empty;
        FirstName = string.Empty;
        LastName = string.Empty;
        Address1 = string.Empty;
        Address2 = string.Empty;
        City = string.Empty;
        State = string.Empty;
        Zip = string.Empty;
        Country = string.Empty;
        WorkPhone = string.Empty;
        HomePhone = string.Empty;
        CellPhone = string.Empty;
        Fax = string.Empty;
        EMailAddress = string.Empty;
    }

    public int ID { get; set; }
    public string AddressCode { get; set; }
    public string ResellerID { get; set; }
    public AddressTypes AddressType { get; set; }
    public string CompanyName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Country { get; set; }
    public string WorkPhone { get; set; }
    public string HomePhone { get; set; }
    public string CellPhone { get; set; }
    public string Fax { get; set; }
    public string EMailAddress { get; set; }
}

GetAddressFromID

    [WebMethod]
    public AddressInfo GetAddressFromID(string securityToken, int addressID)
    {
        AddressInfo returnAddress = null;
        string resellerID = Security.ValidateToken(securityToken);

        if (ValidateResellerID(resellerID, addressID) == false)
            throw new Exception("The ResellerID for this address does not match the SecurityToken ResellerID.");

        using (SqlConnection cn = new SqlConnection(DBConnection.ConnectionString))
        {
            using (SqlCommand cmd = new SqlCommand())
            {
                // Open the connection
                cmd.Connection = cn;

                try
                {
                    cmd.CommandText = "Select * From Addresses Where ID=@AddressID";
                    cmd.Parameters.AddWithValue("@AddressID", addressID);
                    SqlDataAdapter da = new SqlDataAdapter(cmd);
                    DataSet dsAddresses = new DataSet();
                    da.Fill(dsAddresses);

                    returnAddress = (from a in dsAddresses.Tables[0].AsEnumerable()
                                     select new AddressInfo
                                     {
                                         ID = a.Field<int>("ID"),
                                         AddressCode = a.Field<string>("AddressCode"),
                                         ResellerID = a.Field<string>("ResellerID"),
                                         AddressType = (AddressInfo.AddressTypes)Enum.Parse(typeof(AddressInfo.AddressTypes), a.Field<string>("AddressType"), true),
                                         CompanyName = a.Field<string>("CompanyName"),
                                         FirstName = (a.Field<string>("FirstName") == null) ? string.Empty : a.Field<string>("FirstName"),
                                         LastName = (a.Field<string>("LastName") == null) ? string.Empty : a.Field<string>("LastName"),
                                         Address1 = (a.Field<string>("Address1") == null) ? string.Empty : a.Field<string>("Address1"),
                                         Address2 = (a.Field<string>("Address2") == null) ? string.Empty : a.Field<string>("Address2"),
                                         City = (a.Field<string>("City") == null) ? string.Empty : a.Field<string>("City"),
                                         State = (a.Field<string>("State") == null) ? string.Empty : a.Field<string>("State"),
                                         Zip = (a.Field<string>("Zip") == null) ? string.Empty : a.Field<string>("Zip"),
                                         Country = (a.Field<string>("Country") == null) ? string.Empty : a.Field<string>("Country"),
                                         WorkPhone = (a.Field<string>("Phone") == null) ? string.Empty : a.Field<string>("Phone"),
                                         HomePhone = (a.Field<string>("Home") == null) ? string.Empty : a.Field<string>("Home"),
                                         CellPhone = (a.Field<string>("Cell") == null) ? string.Empty : a.Field<string>("Cell"),
                                         Fax = (a.Field<string>("Fax") == null) ? string.Empty : a.Field<string>("Fax"),
                                         EMailAddress = (a.Field<string>("EMailAddress") == null) ? string.Empty : a.Field<string>("EMailAddress")
                                     }).FirstOrDefault<AddressInfo>();

                }
                catch (Exception e)
                {
                    throw new Exception(e.Message + e.StackTrace);
                }
                finally
                {
                    if ((cn != null) && (cn.State != ConnectionState.Closed))
                        cn.Close();
                }
            }
        }

        // We have to get the record first, then determine if the address record resellerid matches the security token resellerid
        if (resellerID != returnAddress.ResellerID)
            throw new Exception("The ResellerID for this address does not match the SecurityToken ResellerID.");

        return returnAddress;
    }

Broken Code:

    private void TestAddresses()
    {
        int addrID = 39294;

        Addresses addresses = new Addresses();
        AddressInfo addr = addresses.GetAddressFromID(csTestSecurityToken, addrID);
        addr.AddressCode = "Test";
        if (addr.AddressCode != "Test")
            throw new Exception("Address code did not match");

        try
        {
            // Try with SNC's security token.  Should error
            addr = addresses.GetAddressFromID("0AABEE33-8618-4EBA-B07A-5D6C8FFABA11", addrID);
            throw new Exception("Invalid resellerid did not throw correctly.");
        }
        catch (Exception ex)
        {
            if (ex.Message != "The ResellerID for this address does not match the SecurityToken ResellerID.")
                throw ex;
        }


        addr = addresses.GetAddressFromAddressCode(csTestSecurityToken, "SLGTest");
        if (addr.AddressCode != "SLGTest")
            throw new Exception("Address code did not match");          

        addr.Address1 = "16 North";
        addr.City = "Highland";
        addr.State = "UT";
        addr.Zip = "84004";

        addresses.UpdateAddress(csTestSecurityToken, addr);

        addresses.DeleteAddress(csTestSecurityToken, addr.ID);
    }

Both of these work

        Addresses addresses = new Addresses();
        AddressInfo addr = addresses.GetAddressFromID(csTestSecurityToken, addrID);
        addr.AddressCode = "Test";
        if (addr.AddressCode != "Test")
            addrID = 0;  // <--------------------- Changed this

        try
        {
            // Try with SNC's security token.  Should error
            addr = addresses.GetAddressFromID("0AABEE33-8618-4EBA-B07A-5D6C8FFABA11", addrID);
            throw new Exception("Invalid resellerid did not throw correctly.");
        }
        catch (Exception ex)
        {
            if (ex.Message != "The ResellerID for this address does not match the SecurityToken ResellerID.")
                throw ex;
        }
                       -----------------------------------------------------------
        Addresses addresses = new Addresses();
        AddressInfo addr = addresses.GetAddressFromID(csTestSecurityToken, addrID);
        addr.AddressCode = "Test";
        if (addr.AddressCode != "Test")
            throw new Exception("Address code did not match");

        //try
        //{
        //    // Try with SNC's security token.  Should error
        //    addr = addresses.GetAddressFromID("0AABEE33-8618-4EBA-B07A-5D6C8FFABA11", addrID);
        //    throw new Exception("Invalid resellerid did not throw correctly.");
        //}
        //catch (Exception ex)
        //{
        //    if (ex.Message != "The ResellerID for this address does not match the SecurityToken ResellerID.")
        //        throw ex;
        //}

Try this code:

public class AddrTest
{
    public string AddressCode { get; set; }
}

public class Test
{
    public void ThrowFail()
    {
        int x = 0;
        AddrTest addrTest = new AddrTest();
        addrTest.AddressCode = "Test";
        if (addrTest.AddressCode != "Test")
            throw new Exception("This shouldn't be executed.");

        try
        {
            x = 1;
        }
        catch { }
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483
Scottie
  • 11,050
  • 19
  • 68
  • 109
  • I edited the original. I found that if I add addr = addr; after the if statement, it works fine. Is addr being disposed too early? – Scottie Jun 20 '11 at 19:53
  • What does `Addresses.GetAddressFromID` look like? – Lasse V. Karlsen Jun 20 '11 at 19:54
  • 1
    @Scottie No, it isn't being disposed too early because your type doesn't implement IDisposable. The `addr` reference is at lease alive until the moment you dereference it to read the AddressCode property value, and even if the object was garbage collected after you read that string property, it would still work. The code in your question *still* doesn't explain the problem, so there must be more to it. – Lasse V. Karlsen Jun 20 '11 at 19:54
  • GetAddressFromID posted in orginial – Scottie Jun 20 '11 at 19:58
  • Is it possible the AddressCode is being altered by another thread? Is it possible there is a zero-width non-printable character in one of the strings (I have seen this before.) – agent-j Jun 20 '11 at 19:58
  • Good call @agent-j, @scottie, can you try retyping the SLGTest strings from scratch, both of them, and see if that helps? ie. remove the strings, quotes and all, and retype them? – Lasse V. Karlsen Jun 20 '11 at 20:00
  • @Agent: The strange this is that if I add the line "addr = addr;" after the if block, it works fine. It appears that the text being compared is correct. – Scottie Jun 20 '11 at 20:01
  • Also, just to be sure, the code in the question, the top two sections of code, that is *actual* code, right? It's not like you're returning an object from a WebMethod, with SLGTest in one of the properties, and then verifying the value in the client, ie. the code is not split up between a server and a client? You have actually executed the exact code, as posted, and it fails? – Lasse V. Karlsen Jun 20 '11 at 20:01
  • Re-typed both lines from scratch. Still the same problem. Why would adding the line "addr = addr;" fix the problem? – Scottie Jun 20 '11 at 20:02
  • Yes, I am running this as a method call from inside the project. It is not going through web services at all at this point. – Scottie Jun 20 '11 at 20:03
  • Ok, try this: Remove the call to Addresses.GetAddressFromID, and just do: `AddressInfo addr = new AddressInfo();` does that change anything? – Lasse V. Karlsen Jun 20 '11 at 20:05
  • 1
    @Scottie, try replacing your `addr = addr` with `GC.KeepAlive (addr);` This will make sure your object is not being collected during the comparison. – agent-j Jun 20 '11 at 20:07
  • 1
    @agent-j Since he's not doing anything fancy in the object I doubt that will make a difference, but since `addr = addr` did, something odd is definitely going on so it couldn't hurt. But, shouldn't be necessary. I still think there's something fishy going on here unrelated to the posted code. – Lasse V. Karlsen Jun 20 '11 at 20:08
  • @Lasse - No change. Still fails. – Scottie Jun 20 '11 at 20:09
  • On a wild guess, are you using PostSharp or any other build-time AOP frameworks? – Lasse V. Karlsen Jun 20 '11 at 20:09
  • 1
    Also, are you executing the code in the server code or in the client code at the moment? I'm asking because if you defined AddressInfo in the server, and then added a web service reference, could the actual client-side code look different, some kind of generated proxy class or whatnot? I must confess not having too much experience with web services. – Lasse V. Karlsen Jun 20 '11 at 20:10
  • @Lasse that's a fantastic suggestion, as the proxy classes generated by a web service reference could easily be fowling things up. – Adam Maras Jun 20 '11 at 20:12
  • @Scottie, is your comparison in an iterator definition (with `yield return`)? – agent-j Jun 20 '11 at 20:12
  • This is all on my dev machine, so it is acting as both the server and client. It is running through IIS, so I guess it's possible there is some kind of proxy issue going on. – Scottie Jun 20 '11 at 20:13
  • Try hitting F12 on AddressInfo in the broken code, see where that takes you. And if nothing else works, and you can, I can come in over TeamViewer and poke the code as well. – Lasse V. Karlsen Jun 20 '11 at 20:15
  • @Scottie a better way to phrase the question would have been: is your first snippet (with the assignment and the comparison) in a different project from your `GetAddressFromID` method? Perhaps one is in a Windows Forms application, and the other in an ASP.NET or WCF service project? – Adam Maras Jun 20 '11 at 20:15
  • @Adam: Nope. Same project. It is a web service, but I'm not accessing as a web service in this code. Since it's in the same project, I am simply creating an instance of the class through CLR. – Scottie Jun 20 '11 at 20:21
  • Just for our sanity... set a breakpoint after `addr.AddressCode = "SLGTest";` and use the debugger to determine the exact value of `addr.AddressCode`. – Adam Maras Jun 20 '11 at 20:24
  • Okay, here is another clue. The very next statement is a try {} block. If I comment out the try block, it works fine. It's almost like the throw wants to throw into that next try? Also if I change the throw to something like addrID = 0; it works. – Scottie Jun 20 '11 at 20:24
  • Can you post the full method the broken code is in? Also, did you try hitting F12 and verifying it's actually using the AddressInfo type you're expecting it to? – Lasse V. Karlsen Jun 20 '11 at 20:26
  • Broken code added. F12 gives me an error: Cannot naviage to 'if'. – Scottie Jun 20 '11 at 20:31
  • @Scottie, is your code in an iterator block with `yield return`? – agent-j Jun 20 '11 at 20:33
  • @agent-j: Not that I know of. I'm not even sure what that is. – Scottie Jun 20 '11 at 20:35
  • That's not the same code, after your edit, what happened to the line of code that sets SLGTest? That disappeared... – Lasse V. Karlsen Jun 20 '11 at 20:36
  • As requested, I deleted and re-typed it, except using Test instead of SLGTest (trying to change everything I could think of). Regardless, it still fails in the same manner. – Scottie Jun 20 '11 at 20:38
  • No, the code you now have edited in, the entire broken method, still contains the *test* for SLGTest, but it seems you're actually relying on the method call on the line above to set that property. Can you verify that it actually does so, since this is not the same code you say you're having problems with... – Lasse V. Karlsen Jun 20 '11 at 20:39
  • I've recreated this problem. See the source at the bottom of original post and see if it happens to you? – Scottie Jun 20 '11 at 20:50
  • How are you executing that code? It runs fine for me, in .NET 3.5 and 4.0, both Debug and Release builds. I created a console app, pasted in your code below the Program class, and added to the Main method: `new Test().ThrowFail();`, and it runs fine. – Lasse V. Karlsen Jun 20 '11 at 20:57
  • Yeah, I tried the same thing in a console app and it worked fine for me too. The failing code is in an ASP.Net 4.0 web app. The code resides in default.aspx.cs. The code snippet fails every time for me on that app, but works perfectly everywhere else. – Scottie Jun 20 '11 at 21:09
  • It appears IIS is the problem somehow. I created a new Web App and if I run it through the local web server, it works fine. As soon as I change it to run through an IIS virtual directory, it fails. – Scottie Jun 20 '11 at 21:12
  • After all these comments, it would help to (1) update the question with a summary and (2) consider deleting all the comments. It's important to fix the title and the question to reflect all of this activity. – S.Lott Jun 22 '11 at 09:54

2 Answers2

2

You're comparing instances. try using .Equals instead.

e.g.

if (!addr.AddressCode.Equals("SLGTest"))
    throw new Exception("Address code did not match");
Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77
  • 5
    There's not enough information in the question to reach that conclusion, although it might be correct. – Lasse V. Karlsen Jun 20 '11 at 19:42
  • Because that isn't the problem. The strings would be compared as string values since the String type overloads the operators for that. There is something other than the code in your question that creates the problem. – Lasse V. Karlsen Jun 20 '11 at 19:57
  • Even if it was a problem of comparing references (and not string values) the snippet given would lead us to believe that, as he's using an identical string constant in both locations, the string would be interned, causing even the references to be equal. – Adam Maras Jun 20 '11 at 20:09
  • @Lasse you might want to read Jeffrey L Whitledge's and John Skeet's answers to [Are string.Equals() and == operator really same?](http://stackoverflow.com/questions/3678792/are-string-equals-and-operator-really-same) – Conrad Frix Jun 22 '11 at 17:01
  • @Conrad: I know that they are not the same, but in *context of string comparison*, this is not the problem. – Lasse V. Karlsen Jun 22 '11 at 17:11
  • @Lasse ok just wasn't sure what you meant there – Conrad Frix Jun 22 '11 at 17:30
1

It appears to be a problem with IIS somehow. If I run the code in a console app, it works exactly as intended. If I create a Web App project running on Visual Studio Dev Web Server it works fine. As soon as I switch over to IIS and create a virtual directory, it fails. I can recreate it in this code. I'm still not sure why, but adding a GC.KeepAlive() fixes the problem.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            new Test().ThrowFail();
        }
    }

    public class AddrTest
    {
        public string AddressCode { get; set; }
    }

    public class Test
    {
        public void ThrowFail()
        {
            int x = 0;
            AddrTest addrTest = new AddrTest();
            addrTest.AddressCode = "Test";
            if (addrTest.AddressCode != "Test")
                throw new Exception("This shouldn't be executed.");

            try
            {
                x = 1;
            }
            catch { }
        }
    }
}
Scottie
  • 11,050
  • 19
  • 68
  • 109