2012-01-06 16 views
7

Devo aggiungere alcune informazioni di query aggiuntive al percorso del file come parametro di query per analizzare il percorso più avanti durante l'elaborazione dei file. Penso che la classe System.Uri possa aiutarmi con questo, ma sembra che non mi dia quello che mi aspettavo per i percorsi dei file locali.Perché System.Uri non riconosce il parametro di ricerca per il percorso del file locale?

var fileUri = new Uri("file:///c://a.txt?select=10") 
// fileUri.AbsoluteUri = "file:///c://a.txt%3Fselect=10" 
// fileUri.Query = "" 

var httpUri = new Uri("http://someAddress/a.txt?select=10") 
// httpUri.AbsoluteUri = "http://someaddress/a.txt?select=10" 
// httpUri.Query = "?select=10" 

Nel caso di "ftp:? //someAddress/a.txt selezionare = 10" - stringa di query è anche vuoto

Capisco che System.Uri probabilmente risolve "a. txt? select = 10 "per correggere il nome del file" a.txt% 3Fselect = 10 ", ma PERCHÉ - come evitarlo?

Grazie in anticipo

+1

@Oded Dal momento che sono Uris. E Uris ha parametri. – ordag

+0

@ordag - Il mio punto è che i server FTP e il sistema operativo non eseguiranno _ tutto con questi parametri. – Oded

+2

@Oded È vero, sono comunque validi. E l'autore vuole analizzare personalmente questi parametri nell'elaborazione successiva. – ordag

risposta

8

Si tratta di un bug che Microsoft non risolverà: Bug 594562 Come si può vedere si propongono di riflessione come soluzione alternativa:

... 
Console.WriteLine("Before"); 
Uri fileUri = new Uri("file://host/path/file?query#fragment"); 
Console.WriteLine("AbsoluteUri: " + fileUri.AbsoluteUri); 
Console.WriteLine("ToString: " + fileUri.ToString()); 
Console.WriteLine("LocalPath: " + fileUri.LocalPath); 
Console.WriteLine("Query: " + fileUri.Query); 
Console.WriteLine("Fragment: " + fileUri.Fragment); 

Type uriParserType = typeof(UriParser); 
FieldInfo fileParserInfo = uriParserType.GetField("FileUri", BindingFlags.Static | BindingFlags.NonPublic); 
UriParser fileParser = (UriParser)fileParserInfo.GetValue(null); 
FieldInfo fileFlagsInfo = uriParserType.GetField("m_Flags", BindingFlags.NonPublic | BindingFlags.Instance); 
int fileFlags = (int)fileFlagsInfo.GetValue(fileParser); 
int mayHaveQuery = 0x20; 
fileFlags |= mayHaveQuery; 
fileFlagsInfo.SetValue(fileParser, fileFlags); 

Console.WriteLine(); 
Console.WriteLine("After"); 
fileUri = new Uri("file://host/path/file?query#fragment"); 
Console.WriteLine("AbsoluteUri: " + fileUri.AbsoluteUri); 
Console.WriteLine("ToString: " + fileUri.ToString()); 
Console.WriteLine("LocalPath: " + fileUri.LocalPath); 
Console.WriteLine("Query: " + fileUri.Query); 
Console.WriteLine("Fragment: " + fileUri.Fragment); 
... 
+0

Grazie - allora è comprensibile, perché non funziona come previsto – Vitaliy

5

parametri della stringa di query non sono validi quando si richiede un file locale.

Quando si richiede un file tramite http il file viene eseguito ed è quindi in grado di leggere ed elaborare la querystring. Quando si richiede un file locale, non viene eseguito e quindi non è possibile utilizzare querystring.

Qual è il motivo per cui si aggiungono i parametri di querystring a una richiesta di file? C'è un altro modo per farlo?

+0

Il motivo per cui sto usando tale costruzione è quello di fare una query semplice e comprensibile - ad esempio l'accesso ai file * file * cartella * txt * -" files /? select = *. txt ", accesso al decimo riga nel file "file.txt? line = 10" – Vitaliy

+0

Intendi dire che quando chiamo il costruttore Uri, tenta davvero di accedere al file? Ho pensato che facesse solo il parsing di url in parti - capisco che probabilmente i protocolli * ftp * e * file * non hanno l'uso per i parametri di query - e la classe Uri fornisce alcune soluzioni di risoluzione dei percorsi interal. Ma come menzionato da @ordag - sono Uris e Uris supporta i parametri di query – Vitaliy

+0

E ancora - le costruzioni di query simili sono usate in XSLT (per esempio con la funzione fn: collection) - è permesso scrivere dopo XPath "count (collection ('file: ///d:/collection/?select=*.xml ')) " – Vitaliy