2012-01-06 37 views
7

Tôi cần phải thêm một số thông tin truy vấn bổ sung vào đường dẫn tệp dưới dạng tham số truy vấn để phân tích cú pháp đường dẫn sau trong quá trình xử lý tệp. Tôi mặc dù rằng System.Uri lớp học có thể giúp tôi với điều này, nhưng có vẻ như nó không cho tôi những gì tôi mong đợi cho đường dẫn tập tin địa phương.Tại sao System.Uri không nhận ra tham số truy vấn cho đường dẫn tệp cục bộ?

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" 

Trong trường hợp của "ftp: //someAddress/a.txt chọn = 10" - chuỗi truy vấn cũng là trống

Tôi hiểu rằng System.Uri lẽ giải quyết "a. txt? select = 10 "để sửa tên tệp" a.txt% 3Fselect = 10 ", nhưng TẠI SAO - cách thoát khỏi điều này?

Cảm ơn trước

+1

@Oded Vì họ là URI. Và Uris có tham số. – ordag

+0

@ordag - Quan điểm của tôi là các máy chủ FTP và hệ điều hành sẽ không thực hiện _anything_ với các tham số này. – Oded

+2

@Oded Đúng vậy, chúng hợp lệ. Và tác giả muốn phân tích cú pháp thông số đó trong quá trình xử lý sau. – ordag

Trả lời

8

Đây là một lỗi mà Microsoft sẽ không sửa chữa: Bug 594562 Như bạn có thể thấy họ đề nghị phản ánh như một cách giải quyết:

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

Cảm ơn - sau đó điều đó là dễ hiểu, tại sao nó không hoạt động như mong đợi – Vitaliy

5

Thông số chuỗi truy vấn không hợp lệ khi yêu cầu tệp cục bộ.

Khi bạn yêu cầu tệp bằng cách sử dụng tệp http được thực thi và do đó có thể đọc và xử lý chuỗi truy vấn. Khi bạn yêu cầu một tệp cục bộ, nó không được thực hiện và do đó không thể sử dụng chuỗi truy vấn.

Lý do bạn thêm thông số chuỗi truy vấn vào yêu cầu tệp là gì? Có cách nào khác để làm điều đó không?

+0

Lý do tại sao tôi sử dụng cấu trúc như vậy là tạo truy vấn đơn giản và dễ hiểu - ví dụ: truy cập vào các tệp * thư mục * * txt * -" files /? select = *. txt ", quyền truy cập vào ngày 10 dòng trong tập tin "file.txt? line = 10" – Vitaliy

+0

Bạn có nghĩa là khi tôi gọi Uri constructor - nó thực sự cố gắng truy cập tập tin? Tôi nghĩ rằng nó chỉ phân tích cú pháp url thành các phần - tôi hiểu rằng có thể các giao thức * ftp * và * file không có cách sử dụng cho các tham số truy vấn - và lớp Uri cung cấp một số giải quyết đường dẫn giữa. Nhưng như @ordag đã đề cập - chúng là Uris và Uris hỗ trợ các tham số truy vấn – Vitaliy

+0

Và một lần nữa - các cấu trúc truy vấn tương tự được sử dụng trong XSLT (ví dụ với chức năng thu thập fn) - nó được phép viết sau "đếm (tập hợp"). ///d:/collection/?select=*.xml ')) " – Vitaliy

Các vấn đề liên quan