Question

I have a really weird issue that I can't figure out with comparing objects on IIS 7. We are in the process of deploying our old IIS 6 based ASP.NET application on IIS 7, however we have this equality comparison issue that we can't seem to figure out.

Let me start out by saying that I have the same assemblies and code running both on IIS 6 and IIS 7, however the comparison of the objects is differing with the same code both on IIS 6 and IIS 7. Here is an example of what my object looks like:

class Country : EntityBase {
    public int CountryID { get; set; }
    public string Name { get; set; }

    public override bool Equals(object obj) {
        if (obj == null || !(obj is Country))
            return false;

        Country c = (Country)obj;
        return CountryID == c.CountryID;
    }

    public override int GetHashCode() {
        return CountryID.GetHashCode();
    }
}

I have the following code in an ASPX page both on IIS 6 and IIS 7:

<% foreach(var country in proposalCountries) { %>
<%= country.Country.CountryID %>
<%= country.Country.CountryID.GetHashCode() %>
<%= country.Country.GetHashCode() %>

<%= proposalCountryServices.Count(c => c.Country == country.Country) %>
<%= proposalCountryServices.Count(c => (c.Country != null && country.Country != null) && c.Country.Equals(country.Country)) %>)
<%= proposalCountryServices.Count(c => Object.Equals(c.Country, country.Country)) %>
<% } %>

Here are my results:

IIS 6:

100 <-- CountryID
100 <-- CountryID Hash Code
100 <-- Country Hash Code

1 <-- Something Found
1 <-- Something Found
1 <-- Something Found

IIS 7:

100 <-- CountryID
100 <-- CountryID Hash Code
100 <-- Country Hash Code

0 <-- Nothing Found
1 <-- Something Found
1 <-- Something Found

Is there a difference between .NET 3.5 SP1 on Windows 2003 vs Windows 2008? I am really at a loss of what the problem could be. Has anybody experienced a similar issue?

Update 1:

To answer Jon's question. The two collections are loaded using NHibernate. But I feel I should reiterate that both IIS 6 and IIS 7 are using the exact same build of the application, so unless NHibernate or DynamicProxy2 is changing how things are loaded based on Windows 2003 or Windows 2007, which I haven't been able to find anything about on Google, I don't know what to make of it.

This is also a system wide issue of whenever I am comparing two of my entity objects. So it could have something to do with the DynamicProxy2 wrapper, but both objects are Country objects and given the overrides I have created everything should work the same in IIS 6 and IIS 7.

Update 2:

This appears to be a DynamicProxy2 or NHibernate issue. Because I tried the following code:

<%
    var c1 = new ICost.Business.Entities.Country {
        CountryID = 100
    };
    var c2 = new ICost.Business.Entities.Country {
        CountryID = 100
    };
%>
<%= c1.CountryID == c2.CountryID %>
<%= c1.GetHashCode() == c2.GetHashCode() %>
<%= c1.Equals(c2) %>
<%= Object.Equals(c1, c2) %>
<%= c1 == c2 %>

And for both IIS 6 and IIS 7 the result was, true, true, true, true, false. See my answer below for what I did to solve this.

Update 3:

This also might have had something to do with it: Looks like you forgot to register the http module with Windsor Castle with IIS7

Was it helpful?

Solution 4

This is the solution that worked for me:

public static bool operator ==(BaseEntity a, BaseEntity b)
{
    return Object.Equals(a, b);
}

public static bool operator !=(BaseEntity a, BaseEntity b)
{
    return !Object.Equals(a, b);
}

Apparently NHibernate or DynamicProxy was doing some kind of magic under Windows 2003 to get the "==" operator to work with out the operator being overloaded.

OTHER TIPS

You haven't explained what proposalCountries and proposalCountryServices are. It looks to me like your Equals method is working just fine, but in IIS7 they contain distinct objects - you've got two objects with the same ID (so Equals matches) but they're distinct objects, so == doesn't match.

Please give details as to how the two collections are loaded - that's likely to be the cause of it.

the difference I see is in case one you wrote

c.Country == country.Country

and in case two it is

c.Country.Equals(country.Country))

so I'd guess that in the latter case he succeeds because he is comparing the CountryIDs of both objects in the first case however he is comparing the objects themself.

Why this works under IE6 I don't know... sorry

You are not using referential equality (see below).

Object.Equals will call an overridden Equals method on your type.

I suspect you have pulled out different instances of the entities from different DataContexts, and added it to a list, and hence using an overriden Equals to try make it work.

Update:

Sorry, not sure if you are using LINQ2SQL.

You could probably fix the issue by overriding the ==/!= operators, but there are some considerations to take with that too.

Update 2:

To understand what I mean, find both instances you deem to be equal (exactly where this issue happens). Set a breakpoint. Now, go &obj1 and enter and &obj2 and enter, you will notice they point to different object addresses. Do this on both IIS 6 and 7.

I am not sure why it is behaving differently on IIS6 and IIS7, but I suspect subtle differences in the page lifecycle could be the cause why they are not referentially equal.

Update 3:

Are you running under classic mode in IIS7? If not, try doing so.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top