2

This question has been asked a million times, and yet none of the responses work for me. The one I was most excited about was Http Post for Windows Phone 8 but because it requires delegates, it's not right for my code... the Postdata function is called from repositories, it would be nice to get a response straight from this function!

How do I add post parameters to this code? I've been trying to get it to work for a good 10 hours now.

// Repository code

string url = "/bla/bla/" + blaId + "/";
Dictionary<string, string> postParams = new Dictionary<string, string>();
postParams.Add("value", message);
string response = await BlaDataContext.PostData(url, postParams);

// ...

public static async Task<string> PostData(string url, Dictionary<String, String> postParams)
{
    HttpWebRequest request = WebRequest.CreateHttp(APIURL + url);
    request.ContentType = "application/x-www-form-urlencoded";
    request.Method = "POST";
    postParams.Add("oauth_token", Contract.AccessToken); // where do I add this to the request??

    try
    {
        HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();

        Debug.WriteLine(response.ContentType);
        Stream responseStream = response.GetResponseStream();
        string data;
        using (var reader = new StreamReader(responseStream))
        {
            data = reader.ReadToEnd();
        }
        responseStream.Close();

        return data;
    }
    catch (Exception e)
    {
        // whatever
    }
}

2 Answers 2

2
HttpWebRequest request = WebRequest.CreateHttp("" + url);
//we could move the content-type into a function argument too.
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
postParams.Add("oauth_token", ""); // where do I add this to the request??
try
{
    //this is how you do it
    using(var stream = await request.GetRequestStreamAsync())
    {
        byte[] jsonAsBytes = Encoding.UTF8.GetBytes(string.Join("&", postParams.Select(pp => pp.Key + "=" + pp.Value)));
        await stream.WriteAsync(jsonAsBytes, 0, jsonAsBytes.Length);
    }
    HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();

    Debug.WriteLine(response.ContentType);
    System.IO.Stream responseStream = response.GetResponseStream();
    string data;
    using (var reader = new System.IO.StreamReader(responseStream))
    {
        data = reader.ReadToEnd();
    }
    responseStream.Close();

    return data;
}

Async Await HttpWebRequest Extensions:

public static class HttpExtensions
{
    public static Task<Stream> GetRequestStreamAsync(this HttpWebRequest request)
    {
        var tcs = new TaskCompletionSource<Stream>();

        try
        {
            request.BeginGetRequestStream(iar =>
           {
               try
               {
                   var response = request.EndGetRequestStream(iar);
                   tcs.SetResult(response);
               }
               catch (Exception exc)
               {
                   tcs.SetException(exc);
               }
           }, null);
        }
        catch (Exception exc)
        {
            tcs.SetException(exc);
        }

        return tcs.Task;
    }
    public static Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request)
    {
        var taskComplete = new TaskCompletionSource<HttpWebResponse>();
        request.BeginGetResponse(asyncResponse =>
        {
            try
            {
                HttpWebRequest responseRequest = (HttpWebRequest)asyncResponse.AsyncState;
                HttpWebResponse someResponse =
                   (HttpWebResponse)responseRequest.EndGetResponse(asyncResponse);
                taskComplete.TrySetResult(someResponse);
            }
            catch (WebException webExc)
            {
                HttpWebResponse failedResponse = (HttpWebResponse)webExc.Response;
                taskComplete.TrySetResult(failedResponse);
            }
        }, request);
        return taskComplete.Task;
    }
}

With the extensions, I think it's a little cleaner.

Sign up to request clarification or add additional context in comments.

2 Comments

With a slight addition to your post, I believe I am getting close... ill make an edit so you can see what I did
Right, I think this is working... it's hard to tell because im getting "oauth token expired" when im sending the correct oauth token...but oh well lol... I must be close now. thanks for the help buddo!
0

You need to write the parameters to the request body.

You could use an extension method like this one:

public static void AddFormData(this HttpWebRequest request, IDictionary<string, string> data)
{
    using (var memStream = new MemoryStream())
    using (var writer = new StreamWriter(memStream))
    {
        bool first = true;
        foreach (var d in data)
        {
            if (!first)
                writer.Append("&");
            writer.Write(Uri.EscapeDataString(d.Key));
            writer.Write("=");
            writer.Write(Uri.EscapeDataString(d.Value));
            first = false;
        }
        writer.Flush();
        request.ContentLength = memStream.Length;
        memStream.Position = 0;
        using (var reqStream = request.GetRequestStream())
        {
            memStream.CopyTo(reqStream);
        }
    }
}

Call it like this:

request.AddFormData(postParams);

2 Comments

Unfortunately request.GetRequestStream does not exist in windows phone 8.
@Jimmyt1988, indeed, you need to use the async version

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.