2012-01-06 8 views
7

Necesito agregar alguna información de consulta adicional a la ruta del archivo como parámetro de consulta para analizar la ruta más tarde durante el procesamiento de archivos. Pensé que la clase System.Uri me puede ayudar con esto, pero parece que no me da lo que esperaba para las rutas locales de archivos.¿Por qué System.Uri no reconoce el parámetro de consulta para la ruta del archivo local?

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" 

En el caso de "ftp:? //someAddress/a.txt seleccione = 10" - cadena de consulta es también vacía

entiendo que System.Uri probablemente resuelve "un . txt? select = 10 "para corregir el nombre de archivo" a.txt% 3Fselect = 10 ", pero ¿POR QUÉ - cómo escapar de esto?

Gracias de antemano

+1

@Oded Puesto que son Uris. Y Uris tiene parámetros. – ordag

+0

@ordag - Mi punto es que los servidores FTP y el sistema operativo no harán _cualquier_ con estos parámetros. – Oded

+2

@Oded Eso es cierto, sin embargo son válidos. Y el autor quiere analizar esos parámetros por sí mismo en el procesamiento posterior. – ordag

Respuesta

8

Este es un error que Microsoft no solucionará: Bug 594562 Como se puede ver que proponen la reflexión como una solución 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

Gracias - entonces es comprensible, por qué no funciona como se esperaba – Vitaliy

5

parámetros de cadena de consulta no son válidos cuando se solicita un archivo local.

Cuando solicita un archivo mediante http, el archivo se ejecuta y, por lo tanto, puede leer y procesar la cadena de consulta. Cuando solicita un archivo local, no se ejecuta y, por lo tanto, no puede utilizar la cadena de consulta.

¿Cuál es la razón por la que está agregando params de querystring a una solicitud de archivo? ¿Hay alguna otra forma de hacerlo?

+0

La razón por la que estoy usando dicha construcción es hacer una consulta simple y comprensible; por ejemplo, acceder a la carpeta * files * * txt * files -" files /? select = *. txt ", acceder al 10mo línea en el archivo "file.txt? line = 10" – Vitaliy

+0

¿Quiere decir que cuando llamo al constructor de Uri, realmente intenta acceder al archivo? Pensé que solo analizaba url en partes: entiendo que probablemente los protocolos * ftp * y * file * no tengan uso para los parámetros de consulta, y la clase Uri proporciona una resolución de ruta interna. Pero como @ordag mencionó - son Uris y Uris, admite los parámetros de consulta – Vitaliy

+0

Y nuevamente - construcciones de consulta similares se usan en XSLT (por ejemplo, con función fn: collection) - se permite escribir después de XPath "count (collection ('file: ///d:/collection/?select=*.xml ')) " – Vitaliy

Cuestiones relacionadas