Как правильно разбирать сложные URL

vbnet2000
Дата: 24.04.2007 23:10:07
Ну когда там больше десятка разных параметров, чтобы на порядке не попадаться. Чтобы например при редиректе легко заменить значение ОДНОГО параметра.
Я вообще-то обычно беру Request.Url.PathAndQuery и разбираю его как строку, но понимаю, что занимаюсь идиотизмом.
Сегодня опять при тестировании попался на этом. А как это делать правильно? Что-нибудь встроенное есть? Ну типа как system.uri - только поглубже?
Dkm_S
Дата: 24.04.2007 23:25:47
А MSDN почитать совсем никак?
--
Абыpвалг! - сказал Linux после pyсификации
vbnet2000
Дата: 24.04.2007 23:33:00
Спасибо, очень информативный совет
ExD
Дата: 25.04.2007 00:31:17
Насчет встроенных средств не уверен, но можно использовать например регулярные варажения(заменяет параметр id на нужное значение):
  string url = Request.RawUrl;
  url = Regex.Replace(url, "(?<=[?&]id=).*?(?=&|$)", "5",RegexOptions.IgnoreCase);
  Response.Redirect(url);
vbnet2000
Дата: 25.04.2007 00:42:03
Да, это вариант конечно. Но нужного параметра может еще и не быть.

Наверное тут лучше ничего не придумаешь, как создать новую коллекцию из Request.Querystring - потом в ней выполнять нужную модификацию, ну а потом по частям собирать опять URL из всех кусков.
Просто задачка-то распространенная, я думал может есть что-то более простое и стандартное.
ExD
Дата: 25.04.2007 01:10:05
Что мешает проверять наличие параметра? Решение с коллекцией кажется слишким громоздким, возможно кто-то знает лучшее решение, интересно
vbnet2000
Дата: 25.04.2007 01:46:58
Сложно проверять все. Мне просто некогда очень сейчас. Хотелось побыстрее. Но я в принципе уже наковырял на скорую руку такое

   Public Shared Function ParseURL(ByVal Key1 As String, ByVal Value1 As String) As String
        Dim Insert As Boolean = False
        Dim PRM As New Collections.Specialized.NameValueCollection
        For Each K As String In HttpContext.Current.Request.QueryString.AllKeys
            If K = Key1 Then
                PRM.Add(K, Value1)
                Insert = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
        Next
        If Not Insert Then PRM.Add(Key1, Value1)
        ''
        Dim NewUrl As New System.Text.StringBuilder(HttpContext.Current.Request.Url.Scheme & "://" & HttpContext.Current.Request.Url.Authority & HttpContext.Current.Request.Url.AbsolutePath)
        If PRM.Count = 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
        ElseIf PRM.Count > 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
            For i As Integer = 1 To PRM.Count - 1
                NewUrl.Append("&" & PRM.Keys(i) & "=" & PRM.Item(i))
            Next
        End If
        Return NewUrl.ToString
    End Function

    Public Shared Function ParseURL(ByVal Key1 As String, ByVal Value1 As String, ByVal Key2 As String, ByVal Value2 As String) As String
        Dim Insert() As Boolean = {False, False}
        Dim PRM As New Collections.Specialized.NameValueCollection
        For Each K As String In HttpContext.Current.Request.QueryString.AllKeys
            If K = Key1 Then
                PRM.Add(K, Value1)
                Insert(0) = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
            If K = Key2 Then
                PRM.Add(K, Value2)
                Insert(1) = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
        Next
        If Not Insert(0) Then PRM.Add(Key1, Value1)
        If Not Insert(1) Then PRM.Add(Key2, Value2)
        ''
        Dim NewUrl As New System.Text.StringBuilder(HttpContext.Current.Request.Url.Scheme & "://" & HttpContext.Current.Request.Url.Authority & HttpContext.Current.Request.Url.AbsolutePath)
        If PRM.Count = 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
        ElseIf PRM.Count > 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
            For i As Integer = 1 To PRM.Count - 1
                NewUrl.Append("&" & PRM.Keys(i) & "=" & PRM.Item(i))
            Next
        End If
        Return NewUrl.ToString
    End Function

    Public Shared Function ParseURL(ByVal Key1 As String, ByVal Value1 As String, ByVal Key2 As String, ByVal Value2 As String, ByVal Key3 As String, ByVal Value3 As String) As String
        Dim Insert() As Boolean = {False, False, False}
        Dim PRM As New Collections.Specialized.NameValueCollection
        For Each K As String In HttpContext.Current.Request.QueryString.AllKeys
            If K = Key1 Then
                PRM.Add(K, Value1)
                Insert(0) = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
            If K = Key2 Then
                PRM.Add(K, Value2)
                Insert(1) = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
            If K = Key3 Then
                PRM.Add(K, Value3)
                Insert(2) = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
        Next
        If Not Insert(0) Then PRM.Add(Key1, Value1)
        If Not Insert(1) Then PRM.Add(Key2, Value2)
        If Not Insert(2) Then PRM.Add(Key2, Value3)
        ''
        Dim NewUrl As New System.Text.StringBuilder(HttpContext.Current.Request.Url.Scheme & "://" & HttpContext.Current.Request.Url.Authority & HttpContext.Current.Request.Url.AbsolutePath)
        If PRM.Count = 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
        ElseIf PRM.Count > 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
            For i As Integer = 1 To PRM.Count - 1
                NewUrl.Append("&" & PRM.Keys(i) & "=" & PRM.Item(i))
            Next
        End If
        Return NewUrl.ToString
    End Function

Ну и так далее. Пользоваться так

Response.Redirect(ParseURL("SID", Session("SemesterID")))
или
Response.Redirect(ParseURL("MainID", Session("MainCategoryID")),"SubID", Session("SubCategoryID"))

Вроде работает. Ну все-провсе почти час наверное ушел. Просто некогда было. Думал что-то готовое есть.
vbnet2000
Дата: 25.04.2007 04:58:39
Хм, случайно заметил, что скопировал вариант с ошибокой. Вдруг кому-то надо будет. Вот так правильно вообще-то.

    Public Shared Function ParseURL(ByVal Key1 As String, ByVal Value1 As String) As String
        Dim Insert As Boolean = False
        Dim PRM As New Collections.Specialized.NameValueCollection
        For Each K As String In HttpContext.Current.Request.QueryString.AllKeys
            If K = Key1 Then
                PRM.Add(K, Value1)
                Insert = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
        Next
        If Not Insert Then PRM.Add(Key1, Value1)
        ''
        Dim NewUrl As New System.Text.StringBuilder(HttpContext.Current.Request.Url.Scheme & "://" & HttpContext.Current.Request.Url.Authority & HttpContext.Current.Request.Url.AbsolutePath)
        If PRM.Count = 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
        ElseIf PRM.Count > 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
            For i As Integer = 1 To PRM.Count - 1
                NewUrl.Append("&" & PRM.Keys(i) & "=" & PRM.Item(i))
            Next
        End If
        Return NewUrl.ToString
    End Function

    Public Shared Function ParseURL(ByVal Key1 As String, ByVal Value1 As String, ByVal Key2 As String, ByVal Value2 As String) As String
        Dim Insert() As Boolean = {False, False}
        Dim PRM As New Collections.Specialized.NameValueCollection
        For Each K As String In HttpContext.Current.Request.QueryString.AllKeys
            If K = Key1 Then
                PRM.Add(K, Value1)
                Insert(0) = True
            ElseIf K = Key2 Then
                PRM.Add(K, Value2)
                Insert(1) = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
        Next
        If Not Insert(0) Then PRM.Add(Key1, Value1)
        If Not Insert(1) Then PRM.Add(Key2, Value2)
        ''
        Dim NewUrl As New System.Text.StringBuilder(HttpContext.Current.Request.Url.Scheme & "://" & HttpContext.Current.Request.Url.Authority & HttpContext.Current.Request.Url.AbsolutePath)
        If PRM.Count = 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
        ElseIf PRM.Count > 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
            For i As Integer = 1 To PRM.Count - 1
                NewUrl.Append("&" & PRM.Keys(i) & "=" & PRM.Item(i))
            Next
        End If
        Return NewUrl.ToString
    End Function

    Public Shared Function ParseURL(ByVal Key1 As String, ByVal Value1 As String, ByVal Key2 As String, ByVal Value2 As String, ByVal Key3 As String, ByVal Value3 As String) As String
        Dim Insert() As Boolean = {False, False, False}
        Dim PRM As New Collections.Specialized.NameValueCollection
        For Each K As String In HttpContext.Current.Request.QueryString.AllKeys
            If K = Key1 Then
                PRM.Add(K, Value1)
                Insert(0) = True
            ElseIf K = Key2 Then
                PRM.Add(K, Value2)
                Insert(1) = True
            ElseIf K = Key3 Then
                PRM.Add(K, Value3)
                Insert(2) = True
            Else
                PRM.Add(K, HttpContext.Current.Request.QueryString(K))
            End If
        Next
        If Not Insert(0) Then PRM.Add(Key1, Value1)
        If Not Insert(1) Then PRM.Add(Key2, Value2)
        If Not Insert(2) Then PRM.Add(Key3, Value3)
        ''
        Dim NewUrl As New System.Text.StringBuilder(HttpContext.Current.Request.Url.Scheme & "://" & HttpContext.Current.Request.Url.Authority & HttpContext.Current.Request.Url.AbsolutePath)
        If PRM.Count = 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
        ElseIf PRM.Count > 1 Then
            NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
            For i As Integer = 1 To PRM.Count - 1
                NewUrl.Append("&" & PRM.Keys(i) & "=" & PRM.Item(i))
            Next
        End If
        Return NewUrl.ToString
    End Function
ExD
Дата: 25.04.2007 11:13:47
Реализация ужасна. Копи-пэйст - зло. Вместо 3 функций для изменения 1,2,3 параметров нужно было написать одну, которой передавался список параметров для изменения. Очень странно выглядит код подобный этому: NewUrl.Append("?" & PRM.Keys(0) & "=" & PRM.Item(0))
Вы мало что выигрываете, используя StringBuilder и вместе с тем обычную конкатенацию строк.
это просто пипетс!
Дата: 25.04.2007 11:17:50
ЭТО КОШМАР ВОЩЕ!
афтар ты в Дели жывешь?