6

I need to POST a JSON string to a page. The page is external and out of my control, and it expects the post data to be in the web-form post format (key1=value1&key2=value2)

How can I convert the JSON string to this format?

4
  • 1
    if you're posting it, it'll show up as a normal post field - json is just text, after all. e.g. $data = json_decode($_POST['name_of_field_you_posted_the_json_as']) Commented Nov 19, 2013 at 14:45
  • I'm confused. You want to POST it but you use the GET format as an example. Commented Nov 19, 2013 at 14:46
  • @MarcB isn't that PHP? what if the page expects just 'application/x-www-form-urlencoded' format? ('key=value' pairs separated by &) Commented Nov 19, 2013 at 14:52
  • 1
    @ArlaudAgbePierre that's the standard format when a HTML form is posting the data to a page Commented Nov 19, 2013 at 14:53

3 Answers 3

12

This can be done by first deserializing your JSON to a Dictionary<string, string>, then iterating through the key-value pairs in the dictionary and building up a querystring from that.

However, keep in mind that querystring format (application/x-www-form-urlencoded) is not a hierarchical format, while JSON is. So your JSON object can only be a simple object with key-value pairs (no arrays or nested objects). If your JSON is more complicated than that, you will have to do some more work to flatten it before you can convert it to a querystring.

Demo:

class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""key1"" : ""value1"",
            ""key2"" : ""value2"",
            ""int"" : 5,
            ""bool"" : true,
            ""decimal"" : 3.14,
            ""punct"" : ""x+y=z""
        }";

        var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

        StringBuilder sb = new StringBuilder();
        foreach (KeyValuePair<string, string> kvp in dict)
        {
            if (!string.IsNullOrEmpty(kvp.Key) && !string.IsNullOrEmpty(kvp.Value))
            {
                if (sb.Length > 0) sb.Append('&');
                sb.Append(HttpUtility.UrlEncode(kvp.Key));
                sb.Append('=');
                sb.Append(HttpUtility.UrlEncode(kvp.Value));
            }
        }
        var postDataString = sb.ToString();

        Console.WriteLine(postDataString);
    }
}

Output:

key1=value1&key2=value2&int=5&bool=True&decimal=3.14&punct=x%2by%3dz

As was mentioned in the comments, you can use the FormUrlEncodedContent class to do the same thing. Replace the StringBuilder and foreach loop in the code above with the following (but note this approach requires async/await):

var formUrlEncodedContent = new FormUrlEncodedContent(dict);
var postDataString = await formUrlEncodedContent.ReadAsStringAsync();
Sign up to request clarification or add additional context in comments.

2 Comments

thanks. I was looking for a method in the framework. but your answer is the most complete.
The FormUrlEncodedContent method can convert your dictionary to the form string. The whole foreach can be replaced by: string urlencodedformdata = new FormUrlEncodedContent(dict);
1

You don't post JSON like that. You set the Content-Type header to "application/json" and then you simply fill the content body with the JSON as-is.

There is no built in support in C# or JSON.NET to serialize JSON into form post data, but you can probably use LINQ to JSON to write a translater yourself relatively easy, assuming the JSON format is simple enough.

3 Comments

what if the page expects just a 'application/x-www-form-urlencoded' format? ('key=value' pairs separated by &)
Well, I assume you could just put the whole JSON string in a key, but honestly, if the page doesn't expect JSON, it's not going to work anyway. You post JSON to pages expecting JSON.
actually my question was how to serialize a JSON string to a form post data. The page is an external resource, I do not have control of it
1

Is the Json being passed in always the same? Your best bet is to deserialize the Json to a C# class then create your post data from that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.