Domanda

Ho un problema davvero strano che non riesco a capire con il confronto di oggetti su IIS 7. Stiamo implementando la nostra vecchia applicazione ASP.NET basata su IIS 6 su IIS 7, tuttavia abbiamo questo problema di confronto di uguaglianza che non riusciamo a capire.

Vorrei iniziare dicendo che ho gli stessi assembly e lo stesso codice in esecuzione su IIS 6 e IIS 7, tuttavia il confronto degli oggetti differisce con lo stesso codice sia su IIS 6 che su IIS 7. Ecco un esempio di come appare il mio oggetto:

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

Ho il seguente codice in una pagina ASPX sia su IIS 6 che su 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)) %>
<% } %>

Ecco i miei risultati:

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

Esiste una differenza tra .NET 3.5 SP1 su Windows 2003 e Windows 2008? Sono davvero in perdita di quale potrebbe essere il problema. Qualcuno ha riscontrato un problema simile?

Aggiornamento 1:

Per rispondere alla domanda di Jon. Le due raccolte vengono caricate utilizzando NHibernate. Ma ritengo di dover ribadire che sia IIS 6 che IIS 7 utilizzano la esatta stessa build dell'applicazione, quindi a meno che NHibernate o DynamicProxy2 stiano cambiando il modo in cui le cose vengono caricate in base a Windows 2003 o Windows 2007, che Non sono stato in grado di trovare nulla su Google, non so cosa farne.

Questo è anche un problema di sistema di ogni volta che sto confrontando due dei miei oggetti entità. Quindi potrebbe avere qualcosa a che fare con il wrapper DynamicProxy2, ma entrambi gli oggetti sono oggetti Country e, date le sostituzioni che ho creato, tutto dovrebbe funzionare allo stesso modo in IIS 6 e IIS 7.

Aggiornamento 2:

Questo sembra essere un problema DynamicProxy2 o NHibernate. Perché ho provato il seguente codice:

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

E sia per IIS 6 che per IIS 7 il risultato è stato, true , true , true , true , false . Vedi la mia risposta qui sotto per quello che ho fatto per risolvere questo problema.

Aggiornamento 3:

Anche questo potrebbe aver avuto qualcosa a che fare con esso: Sembra che tu abbia dimenticato di registrare il modulo http con Windsor Castle con IIS7

È stato utile?

Soluzione 4

Questa è la soluzione che ha funzionato per 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);
}

Apparentemente NHibernate o DynamicProxy stavano facendo un qualche tipo di magia in Windows 2003 per ottenere il " == " operatore per lavorare senza l'operatore sovraccarico.

Altri suggerimenti

Non hai spiegato cosa sono requestCountries e proposCountryServices . Mi sembra che il tuo metodo Equals funzioni bene, ma in IIS7 contengono oggetti distinti: hai due oggetti con lo stesso ID (quindi Equals corrisponde) ma sono oggetti distinti, quindi == non corrisponde .

Fornisci dettagli su come vengono caricate le due raccolte, probabilmente è la causa di ciò.

la differenza che vedo è nel caso in cui tu abbia scritto

c.Country == country.Country

e nel secondo caso è

c.Country.Equals(country.Country))

quindi immagino che in quest'ultimo caso abbia successo perché sta confrontando i CountryID di entrambi gli oggetti nel primo caso, tuttavia sta confrontando gli stessi oggetti.

Perché questo funziona con IE6 non lo so ... scusa

Non stai usando l'uguaglianza referenziale (vedi sotto).

Object.Equals chiamerà un metodo Equals ignorato sul tuo tipo.

Sospetto che tu abbia estratto diverse istanze delle entità da diversi DataContexts e l'hai aggiunto a un elenco, e quindi usando un overriden Equals per provare a farlo funzionare.

Aggiornamento:

Siamo spiacenti, non sono sicuro se si utilizza LINQ2SQL.

Probabilmente potresti risolvere il problema sovrascrivendo gli operatori == /! =, ma ci sono anche alcune considerazioni da prendere.

Aggiornamento 2:

Per capire cosa intendo, trova entrambi i casi che ritieni uguali (esattamente dove si verifica questo problema). Imposta un punto di interruzione. Ora, vai & amp; obj1 e inserisci e & amp; obj2 e inserisci, noterai che puntano a diversi indirizzi di oggetti. Fallo su IIS 6 e 7.

Non sono sicuro del perché si stia comportando diversamente su IIS6 e IIS7, ma sospetto che differenze sottili nel ciclo di vita della pagina potrebbero essere la causa per cui non sono referenzialmente uguali.

Aggiornamento 3:

Stai funzionando in modalità classica in IIS7? In caso contrario, prova a farlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top