2

This code is in python

dataParams = urllib.urlencode({
    "name": "myname",      
    "id": 2,        
    })

    dataReq = urllib2.Request('mylink', dataParams)
    dataRes = urllib2.urlopen(dataReq)

Now i am trying to convert it into C#.Till now I have been able to do this only

 var dataParams = new FormUrlEncodedContent(
             new KeyValuePair<string, string>[]
             {
                 new KeyValuePair<string, string>("name", myname"),                     
                 new KeyValuePair<string, string>("id", "2"),
             });

  httpResponse = await httpClient.PostAsync(new Uri(dataString),dataParams);
  httpResponseBody = await httpResponse.Content.ReadAsStringAsync();   

But my problem is posting the content since the post data needs to be both int and string.But I am able to only send data in string format using FormUrlEncodedContent.So how do I send the post request with proper parameters.

Eugene Podskal
  • 9,882
  • 5
  • 29
  • 51
Uwpbeginner
  • 405
  • 3
  • 15

3 Answers3

4

I am not sure what do you mean by post data needs to be both int and string, because application/x-www-form-urlencoded is basically a string with string key-value pairs.

So it doesn't matter if your original id parameter is a string "2" or a number 2.

It will be encoded the same: name=mynameValue&id=2

So there is nothing wrong with your code. Just use ToString method on original int value to get its string representation:

var id = 2;
var dataParams = new FormUrlEncodedContent(
     new KeyValuePair<string, string>[]
     {
         new KeyValuePair<string, string>("name", myname"),                     
         new KeyValuePair<string, string>("id", id.ToString()),
     });

You can make something like this to urlencode complex types with less boilerplate, and it will even look more like the original python code:

public static class HttpUrlEncode
{
    public static FormUrlEncodedContent Encode(Object obj)
    {
        if (obj == null)
            throw new ArgumentNullException("obj");

        var props = obj
            .GetType()
            .GetProperties(BindingFlags.Instance | BindingFlags.Public)
            .ToDictionary(
                prop => 
                    prop.Name,
                prop => 
                    (prop.GetValue(obj, null) ?? String.Empty).ToString());

        return new FormUrlEncodedContent(props);
    }
}


var dataParams = HttpUrlEncode.Encode(
    new 
    {
        name = "myname",
        id = 2
    });       
Community
  • 1
  • 1
Eugene Podskal
  • 9,882
  • 5
  • 29
  • 51
  • How exactly didn't it work with second approach? I've tried it with simple `[HttpPost] public ActionResult TestPost( String name, Int32 id)` and the action receives correct data. – Eugene Podskal Jan 13 '17 at 10:07
  • No i meant to say that I tried the first and it worked so I didn't tried the second one. :) – Uwpbeginner Jan 13 '17 at 13:13
2

If you don't mind a small library dependency, Flurl [disclosure: I'm the author] makes this as short and succinct as your Python sample, maybe more so:

var dataParams = new {
    name: "myname",
    id: 2
};

var result = await "http://api.com".PostUrlEncodedAsync(dataParams).ReceiveString();
Todd Menier
  • 32,399
  • 14
  • 130
  • 153
0

If your data will contain both number and string values, you can use a KeyValuePair<string,object>, which should accept any of your data. So your code could be:

var contentString = JsonConvert.SerializeObject(
         new KeyValuePair<string, object>[]
         {
             new KeyValuePair<string, object>("name", "myname"),                     
             new KeyValuePair<string, object>("id", 2),
         });
var requestMessage = new HttpRequestMessage(HttpMethod.Post, "URI") {
    Content = new StringContent(contentString)
};
httpResponse = await httpClient.SendAsync(requestMessage);
Vitor M. Barbosa
  • 2,566
  • 22
  • 33
  • 1
    I do not see any [constructors](https://msdn.microsoft.com/en-us/library/system.net.http.formurlencodedcontent(v=vs.118).aspx) on `FormUrlEncodedContent` that accept `IEnumerable`. And the single existing constructor (https://msdn.microsoft.com/en-us/library/system.net.http.formurlencodedcontent.formurlencodedcontent(v=vs.118).aspx) won't accept such parameter. – Eugene Podskal Jan 12 '17 at 18:27
  • @EugenePodskal You're right, I guess it'll have to be `JsonConvert.SerializeObject`, I'll edit accordingly. – Vitor M. Barbosa Jan 12 '17 at 18:35
  • 1
    No, he needs standard [application/x-www-form-urlencoded](http://stackoverflow.com/questions/14551194/how-are-parameters-sent-in-an-http-post-request) encoding. – Eugene Podskal Jan 12 '17 at 18:41
  • 1
    This answer incorrect. OP is asking about posting URL-encoded content, not JSON content. – Todd Menier Jan 13 '17 at 03:23