2014-09-23 16 views
23

Ho il seguente codice C# (da una libreria che sto usando) che cerca di trovare un certificato che paragona l'identificazione personale. Si noti che nel codice seguente sia mycert.Thumbprint sia certificateThumbprint sono stringhe.Perché String.Equals restituisce false?

var certificateThumbprint = AppSettings.CertificateThumbprint; 

var cert = 
    myStore.Certificates.OfType<X509Certificate2>().FirstOrDefault(
     mycert => 
     mycert.Thumbprint != null && mycert.Thumbprint.Equals(certificateThumbprint) 
    ); 

questo non riesce a trovare il certificato con l'identificazione personale, perché è mycert.Thumbprint.Equals(certificateThumbprint)false anche quando le stringhe sono uguali. mycert.Thumbprint == certificateThumbprint restituisce anche false, mentre mycert.Thumbprint.CompareTo(certificateThumbprint) ritorna 0.

enter image description here

potrei mancare qualcosa di ovvio, ma io non riesco a capire il motivo per cui il metodo Equals sta fallendo. Idee?

+15

Questa potrebbe essere una domanda strana ... ma le lunghezze sono le stesse su ogni stringa?(cercando di vedere se ci sono caratteri non stampabili in qualche modo). – vcsjones

+5

Dal file ['string.CompareTo'] (http://msdn.microsoft.com/en-us/library/fkw3h78a (v = vs.110) .aspx): * I set di caratteri ** includono caratteri ignorabili. * * Il metodo CompareTo non considera tali caratteri quando esegue un confronto sensibile alla cultura. Ad esempio, se il codice seguente viene eseguito su .NET Framework 4 o versioni successive, un confronto tra "animal" e "ani-mal" (utilizzando un trattino morbido o U + 00AD) indica che le due stringhe sono equivalenti. * –

+2

@Yuval La tua citazione sembra implicare l'opposto di ciò che sospetti vcsjones. –

risposta

21

CompareTo ignora alcuni caratteri:

static void Main(string[] args) 
{ 
    var a = "asdas"+(char)847;//add a hidden character 
    var b = "asdas"; 
    Console.WriteLine(a.Equals(b)); //false 
    Console.WriteLine(a.CompareTo(b)); //0 
    Console.WriteLine(a.Length); //6 
    Console.WriteLine(b.Length); //5 

    //watch window shows both a and b as "asdas" 
} 

(Qui, il carattere aggiunto al a è U+034F, Combinando Grapheme falegname.)

Debug mode

Quindi il risultato di CompareTo non è un buon indicatore di un bug in Uguali. La ragione più probabile del tuo problema sono i personaggi nascosti. Puoi controllare le lunghezze per essere sicuro.

Vedere this per ulteriori informazioni.

+0

In effetti, avevo due caratteri U + 200E (da sinistra a destra) all'inizio della stringa 'certificateThumbprint'. La rimozione ha risolto il problema. –

+0

Di tutte le risposte questa è quella giusta. Ci sono anche commenti che indicano anche il problema corretto, incluso il collegamento a questa domanda http://stackoverflow.com/questions/11115511/how-to-find-certificate-by-its-thumbprint-in-c-sharp. Segnalo come risposta accettata. Vorrei poterlo fare anche per i commenti. –

2

È possibile provare a utilizzare un sovraccarico di String.Equals che accetta un parametro di tipo StringComparison.

Ad esempio:

myCert.Thumbprint.Equals(certificateThumbprint, StringComparison.[SomeEnumeration]) 


Dove [SomeEnumeration] è sostituito con uno dei seguenti costanti enumerate:

- CurrentCulture 
- CurrentCultureIgnoreCase 
- InvariantCulture 
- InvariantCultureIgnoreCase 
- Ordinal 
- OrdinalIgnoreCase 


riferimento alla documentazione MSDN trovato here. enter image description here

+0

Ho provato con 'OrdinalIgnoreCase' e ​​il risultato è stato lo stesso (cioè falso). –

0

A volte, quando inseriamo i dati nel database che memorizza alcuni spazi come "domanda". E quando proverai a confrontarlo con "domanda" restituisce falso. Quindi il mio suggerimento è: controlla il valore nel database o usa il metodo Trim().

Nel tuo caso, prova: mycert.Thumbprint = null & & mycert.Thumbprint.trim() equals (certificateThumbprint.trim())

penso che restituisce true se esiste!. il record esisterà.

Problemi correlati