DreamTeK
DreamTeK

Reputation: 34287

How to remove a single instance from a NameValueCollection?

Assuming the following url:

Dim nvc As NameValueCollection = HttpUtility.ParseQueryString(http://localhost/Index.aspx?A=23&A=7&A=1)

How can I remove a specific instance of A from a NameValueCollection?

I can add an additional entry

nvc.Add("A", 10)

But can only seem to remove all instances

nvc.Remove("A")

I would prefer not to use string hacks.

Upvotes: 0

Views: 126

Answers (2)

Jimi
Jimi

Reputation: 32288

Try out this method, string manipulation is not abused (I think).

The method extracts the Query part, selects the values of the Key specified except the values to remove, then rebuilds the Query using the UriBuilder.Query property (which can be set), finally returning a new formed Uri, missing the removed Key-Value pairs.

Dim key As String = "A"
Dim valuesToRemove As String() = {"23", "1"}
Dim loc = New Uri("http://localhost/Index.aspx?A=23&A=7&A=1&B=2&B=4&C=23")

Dim newUri As Uri = UriRemoveKeyValues(loc, key, valuesToRemove)

Imports System.Web

Private Function UriRemoveKeyValues(uri As Uri, Key As String, Values As String()) As Uri
    Dim nvc = HttpUtility.ParseQueryString(uri.Query)
    Dim keyValues = nvc.GetValues(Key).Except(Values).ToList()
    nvc.Remove(Key)
    keyValues.ForEach(Sub(s) nvc.Add(Key, s))
    Dim builder As New UriBuilder(uri) With {
        .Query = nvc.ToString()
    }
    Return builder.Uri
End Function

You could also just get the Uri.Query, split and rebuild the same way.
More string manipulations, though.

Upvotes: 2

Andrew Morton
Andrew Morton

Reputation: 25057

You can use the GetValues(String) method to get an array of the values. You can then create a new list or whatever is appropriate from that array, e.g.:

Dim loc = New Uri("http://localhost/Index.aspx?A=23&A=7&A=1")
Dim nvc As NameValueCollection = HttpUtility.ParseQueryString("&" & loc.Query.TrimStart("?"c))

Dim myValues As New List(Of String)

Dim vals = nvc.GetValues("A")
If vals IsNot Nothing Then
    myValues = vals.Where(Function(v) v <> "7").ToList()
End If

Console.WriteLine(String.Join(vbCrLf, myValues))

Outputs:

23
1

[I had to do that to the URI to get ParseQueryString to extract the first "A".]

Upvotes: 1

Related Questions