4
votes

Learning F# while trying to do something useful at the same time, so this is kind of basic question:

I have req, which is a HttpListenerRequest, which has QueryString property, with type System.Collections.Specialized.NameValueCollection. So, for sake of clarity let's say, I have

let queryString = req.QueryString

Now I want to produce nice string (not printf to console) from contents of that, but queryString.ToString() is not overriden apparently, so it just gives string "System.Collections.Specialized.NameValueCollection".

So, what's the F# one-liner to get a nice string out of that, like "key1=value1\nkey2=value2\n..."?

4

4 Answers

4
votes
nvc.AllKeys
|> Seq.map (fun key -> sprintf "%s=%s" key nvc.[key])
|> String.concat "\n"
4
votes

Something like this ought to work:

let nvcToString (nvc:System.Collections.Specialized.NameValueCollection) =
    System.String.Join("\n", 
                       seq { for key in nvc -> sprintf "%s=%s" key nvc.[key] })
1
votes

I use this code, which handles the case of keys that have multiple values, which is legal in a NameValueCollection, and I'm not seeing in the other answers. I'm also using the MS AntiXSS library to URL-encode the values.

Edit: Oops, I didn't read the OP closely enough. I assumed you wanted to turn Request.QueryString back into an actual query string. I'm going to leave this answer because it's still true that NameValueCollection allows more than one value per key.

type NameValueCollection with
    /// Converts the collection to a URL-formatted query string.
    member this.ToUrlString() =
        // a key can have multiple values, so flatten this out, repeating the key if necessary
        let getValues (key:string) =
            let kEnc = Encoder.UrlEncode(key) + "="
            this.GetValues(key)
            |> Seq.map (fun v -> kEnc + Encoder.UrlEncode(v))

        let pairs = this.AllKeys |> Seq.collect getValues

        String.Join("&", pairs)
0
votes

kvs.AllKeys |> Seq.map (fun i -> i+ " = " + kvs.[i]) |> Seq.fold (fun s t -> s + "\n" + t) ""

Extra inefficient and creating lots of string instances, directly from my head. :)