简体   繁体   中英

HTTP request with C#

I want to convert the Object received in the function and do as needed to convert it to an object ({"some_key": "some_value"}) .

Here is my code:

public HttpRequests(string url, string method, Object data)
{

   //The following prepares data, according to received parameter

    if (data is Array)
    {
        data = (Array)data;
    }
    else if (data is Dictionary<Object, Object>)
    {
        data = ((Dictionary<string, string>)data)["something"] = platform_secret;
        data = ((Dictionary<string, string>)data)["something2"] = "1";
    }

    method = method.ToUpper(); //POST or GET

    this.url = just_url + url;
    this.data = Newtonsoft.Json.JsonConvert.SerializeObject(data);
    this.method = method;

}

public Object performRequest()
{

    if (this.data != null && url != null)
    {

        WebRequest request = HttpWebRequest.Create(url);

        byte[] data_bytes = Encoding.ASCII.GetBytes(Convert.ToChar(data)[]);
        //^ this does not work. Am I supposed to do this?
        // as I said, what I want is to get an object {key: something} that can be read
        //      by $_POST["key"] in the server

        request.Method = method;
        request.ContentType = "application/x-www-form-urlencoded"; //TODO: check
        //request.ContentLength = ((Dictionary<string, string>) data);
        request.ContentLength = data_bytes.Length;

        Stream dataStream = request.GetRequestStream(); //TODO: not async at the moment

        //{BEGIN DOUBT

        dataStream.Write(data_bytes, 0, data_bytes.Length);
        dataStream.Close();

        //DOUBT: DO THIS ^ or THIS:_      ???

        StreamWriter writer = new StreamWriter(dataStream);
        writer.Write(this.data);

        //End DOUBT}

        WebResponse response = request.GetResponse();
        Stream dataResponse = response.GetResponseStream();

        writer.Close();
        response.Close();
        dataStream.Close();

        return dataResponse.

    }

What exactly am I missing here?

As you initially assign this.data = Newtonsoft.Json.JsonConvert.SerializeObject(data); , suppose his.data has type string (you can change if it is otherwise).

Then instead of byte[] data_bytes = Encoding.ASCII.GetBytes(Convert.ToChar(data)[]); you need to write just byte[] data_bytes = Encoding.ASCII.GetBytes(data);

After use this

//{BEGIN DOUBT

        dataStream.Write(data_bytes, 0, data_bytes.Length);
        dataStream.Close();

It will help to do the call with some data but it does not help to solve your problem. request.ContentType = "application/x-www-form-urlencoded"; does not expect that the data is Newtonsoft.Json.JsonConvert.SerializeObject serialized. It expects a string containing & separated pairs that are urlencoded.

name1=value1&name2=value2&name3=value3

So, you need to use this format instead of JSON.

You need to use the first piece of code. Here is and exmaple. But the second piece could work too, I guess. You have missed nothing on C# side. A problem could be in the data you are going to transfer, however. If it is not correctly encoded, for example.

You should be doing something closer to the lines of this...

void Main()
{

    var formSerializer = new FormEncodedSerializer();
    formSerializer.Add("key", "value");
    formSerializer.Add("foo", "rnd");
    formSerializer.Add("bar", "random");

    var uri = @"http://example.com";
    var contentType = @"application/x-www-form-urlencoded";
    var postData = formSerializer.Serialize();
    var http = new Http();

    Console.WriteLine (http.Post(uri, postData, contentType));
}


public class Http
{
    public string Post(string url, string data, string format)
    {
        var content = Encoding.UTF8.GetBytes(data);
        var contentLength = content.Length;

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.ServicePoint.Expect100Continue = false;
        request.Method = "POST";
        request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        request.ContentType = format;
        request.ContentLength = contentLength;

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(content, 0, content.Length);
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        using (Stream responseStream = response.GetResponseStream())
        using (StreamReader reader = new StreamReader(responseStream))
        {
            return reader.ReadToEnd();
        }
    }
}`


public class FormEncodedSerializer
{
    private Dictionary<string, string> formKeysPairs;

    public FormEncodedSerializer(): this(new Dictionary<string, string>())
    {
    }

    public FormEncodedSerializer(Dictionary<string, string> kvp)
    {
        this.formKeysPairs = kvp;
    }

    public void Add(string key, string value)
    {
        formKeysPairs.Add(key, value);
    }  

    public string Serialize()
    {
        return string.Join("", this.formKeysPairs.Select(f => string.Format("&{0}={1}", f.Key,f.Value))).Substring(1);
    }

    public void Clear()
    {
        this.formKeysPairs.Clear();
    }  
}

I did not really understand what your service expects, in which format you have to send the data. Anyway, if you set ContentType like "application/x-www-form-urlencoded", you must encode your data with this format. You can simply do it with this code;

var values = ((Dictionary<string, string>)data).Aggregate(
                    new NameValueCollection(),
                    (seed, current) =>
                    {
                        seed.Add(current.Key, current.Value);
                        return seed;
                    });

So, your data is sent like "something=platform_secret&something2=1"

Now, you can send form data simply:

WebClient client = new WebClient();
var result = client.UploadValues(url, values);

I think your first function with signature public HttpRequests(string url, string method, Object data) dosn't seem have any logical error but in your second function with signature public Object performRequest() you have some issue:

  • if your HTTP method is GET you don't need to write content stream.
  • if your method is POST and your data are JSON you need setting up HTTP requester like this:

     request.ContentType = "application/json"; 

and finally, flush your stream before you close it, like this request.Flush();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM