-1

I want to send a post request to an API with some parameters they ask for... I ended up just creating a string, it's ugly but I do not know a way of making it work differently. I then found lots of variations on this WebRequest class, but unfortunately I cannot get it to work.

Main problem is probably because I am not really understanding how this is all fitting together but basically, the examples I have been following use WebRequest method GetResponse... even on MSDN it has this, so I am wondering why when I try to call it in my code, I am not getting that choice? Same goes for GetRequestStream.

enter image description here

How to add parameters into a WebRequest?

        *****DBContext()
        {
            data = "grant_type=" + GRANTTYPE + "&username=" + username + "&password=" + password + "&client_id=" + CLIENTID + "&redirect_uri=" + REDIRECTURI + "&client_secret=" + CLIENTSECRET;
        }

        public bool Authenticate()
        {   
            byte[] dataStream = Encoding.UTF8.GetBytes(data);
            WebRequest webRequest = WebRequest.Create(urlPath);
            webRequest.Method = "POST";
            webRequest.ContentType = "application/json";
            webRequest.ContentLength = dataStream.Length;  
            Stream newStream = webRequest.GetRequestStream();
            // Send the data.
            newStream.Write(dataStream, 0, dataStream.Length);
            newStream.Close();
            WebResponse webResponse = webRequest.GetResponse();

            return true;
        }

I also have the question of when I finally do get this stuff to work, what should I be putting in the callback uri. if it's a phone, is it running off of localhost?

Community
  • 1
  • 1
Jimmyt1988
  • 20,466
  • 41
  • 133
  • 233
  • Still same compile errors though. – Jimmyt1988 Sep 15 '13 at 20:16
  • 1
    Not sure what your question is. Are you trying to parse response ? – fahadash Sep 15 '13 at 20:18
  • First time ever I am writing code to send a post request to an external website's API in C#. that API will return a json string. https://developers.podio.com/authentication/username_password . It's not working, it's saying that webRequest does not have a method GetResponse or GetRequestSream – Jimmyt1988 Sep 15 '13 at 20:22

1 Answers1

1

The .NET compilation for Windows Phone contains an implementation of the WebRequest class which does not have synchronous methods for obtaining request stream and response, as these would block execution on the UI thread until the operations completed. You can use the existing Begin/End methods directly with callback delegates, or you can wrap those calls in async extensions that will give you the kind of readability and functionality you're used to (more or less). My preferred method is defining extensions, so I will demonstrate this method, but it has no performance advantage over the callback pattern. It does have the up-side of being easily portable any time you need to make use of a WebRequest.

Async/Await Pattern

Define custom extensions for the WebRequest class:

public static class Extensions
{
    public static System.Threading.Tasks.Task<System.IO.Stream> GetRequestStreamAsync(this System.Net.WebRequest wr)
    {
        if (wr.ContentLength < 0)
        {
            throw new InvalidOperationException("The ContentLength property of the WebRequest must first be set to the length of the content to be written to the stream.");
        }

        return Task<System.IO.Stream>.Factory.FromAsync(wr.BeginGetRequestStream, wr.EndGetRequestStream, null);
    }

    public static System.Threading.Tasks.Task<System.Net.WebResponse> GetResponseAsync(this System.Net.WebRequest wr)
    {
        return Task<System.Net.WebResponse>.Factory.FromAsync(wr.BeginGetResponse, wr.EndGetResponse, null);
    }
}

Use the new extensions (be sure to import the namespace where your static Extensions class was defined):

public async System.Threading.Tasks.Task<bool> AuthenticateAsync()
{
    byte[] dataStream = System.Text.Encoding.UTF8.GetBytes("...");
    System.Net.WebRequest webRequest = System.Net.WebRequest.Create("...");
    webRequest.Method = "POST";
    webRequest.ContentType = "application/json";
    webRequest.ContentLength = dataStream.Length;
    Stream newStream = await webRequest.GetRequestStreamAsync();
    // Send the data.
    newStream.Write(dataStream, 0, dataStream.Length);
    newStream.Close();
    var webResponse = await webRequest.GetResponseAsync();

    return true;
}

Regarding your final note, at the moment I don't see enough information to make sense of what the callback URI is, where it's defined, and how it affects what you're doing.

lsuarez
  • 4,952
  • 1
  • 29
  • 51
  • the Microsoft.Bcl.Async nuget package already have a lot of async/await extension method (including the one for HttpWebRequest) – Benoit Catherinet Sep 18 '13 at 23:28
  • This question isn't regarding that package. – lsuarez Sep 19 '13 at 02:56
  • That was a comment on your answer not the question, just saying that there is no use to create the exact same extension method that Microsoft already created :) – Benoit Catherinet Sep 19 '13 at 10:17
  • Honestly I'd prefer not to pull in entire libraries when not necessary, especially since I won't have control over its functionality. I don't think something that can be solved with a simple extension warrants a library reference. – lsuarez Sep 19 '13 at 14:28
  • GetRequestStreamAsync() not found. – Ashish-BeJovial Feb 05 '14 at 11:10
  • @AshishJain It's defined in the extensions at the beginning of the post. You're not importing those extensions correctly. – lsuarez Feb 05 '14 at 17:08