2010-02-23 40 views
12

tôi cần phải yêu cầu URL sau bên trong ứng dụng của tôi:System.Net.Uri với các nhân vật urlencoded

http://feedbooks.com/type/Crime%2FMystery/books/top 

Khi tôi chạy đoạn mã sau:

Uri myUri = new Uri("http://feedbooks.com/type/Crime%2FMystery/books/top"); 

Các constructor Uri giải mã %2F vào một chữ số / và tôi nhận được lỗi 404 vì nó đã thay đổi URL thành:

http://feedbooks.com/type/Crime/Mystery/books/top 

Lớp Uri có một hàm tạo có tham số dontEscape, nhưng hàm khởi tạo đó không còn được dùng nữa và đặt nó thành true không có hiệu lực.

Suy nghĩ đầu tiên của tôi là phải làm một cái gì đó như:

Uri myUri = new Uri("http://feedbooks.com/type/Crime%252FMystery/books/top"); 

Với hy vọng rằng nó sẽ chuyển đổi %25 vào một chữ %, nhưng điều đó không làm việc, hoặc.

Bất kỳ ý tưởng nào về cách tạo đối tượng Uri chính xác cho URL cụ thể này trong .NET?

+0

um ... bạn đã thử \% (hoặc \\%) ... :( – apandit

+0

Tôi thích câu hỏi. Bây giờ, xin vui lòng cho một câu trả lời cho Java java.io.URI trong đó có chết tiệt cùng vấn đề, nhưng không có cờ (gần như tôi có thể nói) – davidbak

Trả lời

5

Tôi chạy vào cùng một vấn đề sử dụng 2.0 ...

tôi phát hiện ra một cách giải quyết đăng tại this blog:

// System.UriSyntaxFlags is internal, so let's duplicate the flag privately 
private const int UnEscapeDotsAndSlashes = 0x2000000; 

public static void LeaveDotsAndSlashesEscaped(Uri uri) 
{ 
    if (uri == null) 
    { 
     throw new ArgumentNullException("uri"); 
    } 

    FieldInfo fieldInfo = uri.GetType().GetField("m_Syntax", BindingFlags.Instance | BindingFlags.NonPublic); 
    if (fieldInfo == null) 
    { 
     throw new MissingFieldException("'m_Syntax' field not found"); 
    } 
    object uriParser = fieldInfo.GetValue(uri); 

    fieldInfo = typeof(UriParser).GetField("m_Flags", BindingFlags.Instance | BindingFlags.NonPublic); 
    if (fieldInfo == null) 
    { 
     throw new MissingFieldException("'m_Flags' field not found"); 
    } 
    object uriSyntaxFlags = fieldInfo.GetValue(uriParser); 

    // Clear the flag that we don't want 
    uriSyntaxFlags = (int)uriSyntaxFlags & ~UnEscapeDotsAndSlashes; 

    fieldInfo.SetValue(uriParser, uriSyntaxFlags); 
} 

Nó hoạt động một cách hoàn hảo.

Hy vọng điều này sẽ giúp (tốt hơn bao giờ hết!)

+0

Tuyệt vời! Stackoverflow không bao giờ ngừng làm tôi kinh ngạc. –

+0

Vui vì tôi có thể giúp ... –

2

Đây là một số bug Tôi đã nộp lại một lúc. Nó được cho là cố định trong 4.0, nhưng tôi không nín thở. Rõ ràng nó vẫn là một vấn đề trong RC.

+0

Ah Bạn có biết cách giải quyết nào cho việc triển khai 3.5 không? –

+0

Xin lỗi, nhưng tôi chưa tìm được cách giải quyết nào cho vấn đề này. –

7

Dễ dàng hơn một chút trong .NET 4.0. Bạn có thể đặt cài đặt trong tệp cấu hình của mình như sau:

<uri> 
<schemeSettings> 
    <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" /> 
</schemeSettings> 
</uri> 

Chỉ hoạt động cho các lược đồ 'http' và 'https'.

Hoặc đây là phiên bản mới của phương thức LeaveDotsAndSlashesEscaped. Nó không cần một ví dụ Uri Đặc biệt, chỉ cần gọi nó khi ứng dụng của bạn khởi động:

private void LeaveDotsAndSlashesEscaped() 
{ 
    var getSyntaxMethod = 
     typeof (UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic); 
    if (getSyntaxMethod == null) 
    { 
     throw new MissingMethodException("UriParser", "GetSyntax"); 
    } 

    var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" }); 

    var setUpdatableFlagsMethod = 
     uriParser.GetType().GetMethod("SetUpdatableFlags", BindingFlags.Instance | BindingFlags.NonPublic); 
    if (setUpdatableFlagsMethod == null) 
    { 
     throw new MissingMethodException("UriParser", "SetUpdatableFlags"); 
    } 

    setUpdatableFlagsMethod.Invoke(uriParser, new object[] {0}); 
} 
1

Bằng cách kết hợp 2 câu trả lời trước bạn có thể có một phương pháp bạn chỉ cần gọi một lần cho mỗi quá trình làm việc cả trên. net 4 và .net 3.5.

// System.UriSyntaxFlags is internal, so let's duplicate the flag privately 
private const int UnEscapeDotsAndSlashes = 0x2000000; 

private void LeaveDotsAndSlashesEscaped() 
{ 
    var getSyntaxMethod = 
     typeof (UriParser).GetMethod("GetSyntax", BindingFlags.Static | BindingFlags.NonPublic); 
    if (getSyntaxMethod == null) 
    { 
     throw new MissingMethodException("UriParser", "GetSyntax"); 
    } 

    var uriParser = getSyntaxMethod.Invoke(null, new object[] { "http" }); 

    FieldInfo flagsFieldInfo = typeof(UriParser).GetField("m_Flags", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField | BindingFlags.Instance); 

    if (flagsFieldInfo == null) 
    { 
     throw new MissingFieldException("UriParser", "m_Flags"); 
    } 
    int flags = (int) flagsFieldInfo.GetValue(uriParser); 
    // unset UnEscapeDotsAndSlashes flag and leave the others untouched 
    flags = flags & ~UnEscapeDotsAndSlashes; 
    flagsFieldInfo.SetValue(uriParser, flags); 

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