36

I am trying to make a json call using C#. I made a stab at creating a call, but it did not work:

public bool SendAnSMSMessage(string message)
{
    HttpWebRequest request = (HttpWebRequest)
                             WebRequest.Create("http://api.pennysms.com/jsonrpc");
    request.Method = "POST";
    request.ContentType = "application/json";

    string json = "{ \"method\": \"send\", "+
                  "  \"params\": [ "+
                  "             \"IPutAGuidHere\", "+
                  "             \"msg@MyCompany.com\", "+
                  "             \"MyTenDigitNumberWasHere\", "+
                  "             \""+message+"\" " +
                  "             ] "+
                  "}";

    StreamWriter writer = new StreamWriter(request.GetRequestStream());
    writer.Write(json);
    writer.Close();

    return true;
}

Any advice on how to make this work would be appreciated.

Vaccano
  • 78,325
  • 149
  • 468
  • 850
  • 1
    Are you getting any errors? What does your `message` look like? Are you using a proper API key? – Richard Marskell - Drackir Feb 13 '11 at 06:27
  • @Drackir - I am using the correct API Key (I tested it with an email version of the api and it worked). I don't get any errors. I just don't get a text message. The message is just some simple test message text ("testing sms" (but no quotes)). – Vaccano Feb 13 '11 at 06:35
  • 1
    where is your response? You make a request but you don't use GetResponseStream? – Shiv Kumar Feb 13 '11 at 07:49
  • 2
    @Vaccano, what version of C# are you using? If you're using 3.5/4.0, have you take a look at the WCF REST Starter kit? They have a HttpClient class that makes calling JSON (and other) services a breeze to call. You don't have to muck about with the raw HttpWebRequest etc. Take a look at this document http://msdn.microsoft.com/en-us/library/ee391967.aspx scroll to the Consuming RESTful Services with HttpClient section (towards the bottom. – Shiv Kumar Feb 13 '11 at 09:45
  • @Vaccano, looking at the penny SMS documentation they required the content type to be text/json. Not sure if this will make a difference but you should change it in your code. – Shiv Kumar Feb 13 '11 at 09:48
  • @Shiv Kumar - I did not know I needed a response (or how to get it). I am new the the whole WebRequest thing. --- I will take a look at the REST Starter kit. This is the only json call in all my code, so I would not want to add to much infrastructure to call it. If it can be done with out a lot of additions to my code base then I think I would like it. --- I changed my code to use text/json and it still did not work. But thanks for the heads up on that. – Vaccano Feb 13 '11 at 17:35
  • @Shiv Kumar - once I put a call to request.GetResponse() in the code it worked great! Thanks for the tip (if you put it as an answer I will select it). – Vaccano Feb 13 '11 at 22:21

5 Answers5

42

In your code you don't get the HttpResponse, so you won't see what the server side sends you back.

you need to get the Response similar to the way you get (make) the Request. So

public static bool SendAnSMSMessage(string message)
{
  var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://api.pennysms.com/jsonrpc");
  httpWebRequest.ContentType = "text/json";
  httpWebRequest.Method = "POST";

  using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
  {
    string json = "{ \"method\": \"send\", " +
                      "  \"params\": [ " +
                      "             \"IPutAGuidHere\", " +
                      "             \"msg@MyCompany.com\", " +
                      "             \"MyTenDigitNumberWasHere\", " +
                      "             \"" + message + "\" " +
                      "             ] " +
                      "}";

    streamWriter.Write(json);
  }
  var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
  using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
  {
    var responseText = streamReader.ReadToEnd();
    //Now you have your response.
    //or false depending on information in the response
    return true;        
  }
}

I also notice in the pennysms documentation that they expect a content type of "text/json" and not "application/json". That may not make a difference, but it's worth trying in case it doesn't work.

Shiv Kumar
  • 9,599
  • 2
  • 36
  • 38
8

just continuing what @Mulki made with his code

public string WebRequestinJson(string url, string postData)
{
    string ret = string.Empty;

    StreamWriter requestWriter;

    var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
    if (webRequest != null)
    {
        webRequest.Method = "POST";
        webRequest.ServicePoint.Expect100Continue = false;
        webRequest.Timeout = 20000;

        webRequest.ContentType = "application/json";
        //POST the data.
        using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
        {
            requestWriter.Write(postData);
        }
    }

    HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
    Stream resStream = resp.GetResponseStream();
    StreamReader reader = new StreamReader(resStream);
    ret = reader.ReadToEnd();

    return ret;
}
Patric
  • 72
  • 5
jaysonragasa
  • 1,076
  • 1
  • 20
  • 40
7

Here's a variation of Shiv Kumar's answer, using Newtonsoft.Json (aka Json.NET):

public static bool SendAnSMSMessage(string message)
{
    var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://api.pennysms.com/jsonrpc");
    httpWebRequest.ContentType = "text/json";
    httpWebRequest.Method = "POST";

    var serializer = new Newtonsoft.Json.JsonSerializer();
    using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
    {
        using (var tw = new Newtonsoft.Json.JsonTextWriter(streamWriter))
        {
             serializer.Serialize(tw, 
                 new {method= "send",
                      @params = new string[]{
                          "IPutAGuidHere", 
                          "msg@MyCompany.com",
                          "MyTenDigitNumberWasHere",
                          message
                      }});
        }
    }
    var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
    using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
    {
        var responseText = streamReader.ReadToEnd();
        //Now you have your response.
        //or false depending on information in the response
        return true;        
    }
}
Community
  • 1
  • 1
Diego
  • 18,035
  • 5
  • 62
  • 66
4

If your function resides in an mvc controller u can use the below code with a dictionary object of what you want to convert to json

Json(someDictionaryObj, JsonRequestBehavior.AllowGet);

Also try and look at system.web.script.serialization.javascriptserializer if you are using .net 3.5

as for your web request...it seems ok at first glance..

I would use something like this..

public void WebRequestinJson(string url, string postData)
    {
    StreamWriter requestWriter;

    var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
    if (webRequest != null)
    {
        webRequest.Method = "POST";
        webRequest.ServicePoint.Expect100Continue = false;
        webRequest.Timeout = 20000;

        webRequest.ContentType = "application/json";
        //POST the data.
        using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
        {
            requestWriter.Write(postData);
        }
    }
}

May be you can make the post and json string a parameter and use this as a generic webrequest method for all calls.

Whimsical
  • 5,985
  • 1
  • 31
  • 39
  • What is the point of this: `var webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;` why not just: `HttpWebRequest webRequest = System.Net.WebRequest.Create(url);`? – Richard Marskell - Drackir Feb 13 '11 at 09:09
  • 4
    @Drackir, WebRequest is an abstract class. It's (static) Create method (which is essentially a Factory method) creates an instance of the appropriate class depending in the Uri scheme. Meaning that if the Uri scheme is determined to be "http", then it creates as instance of HttpWebRequest. If it is "ftp" it will create an instance of FtpWebRequest. By doing the "as" the variable webRequest is typed as an instance of HttpWebRequest and so properties and methods specific to that class will be available. Does that make sense? I would call the variable httpWebRequest (just to be clearer). – Shiv Kumar Feb 13 '11 at 09:30
  • This is the MSDN documentation for this, just in case. http://msdn.microsoft.com/en-us/library/bw00b1dc.aspx – Shiv Kumar Feb 13 '11 at 09:32
  • Alas, I am not using MVC. I will try out your changes to my web request though. – Vaccano Feb 13 '11 at 17:36
1

Its just a sample of how to post Json data and get Json data to/from a Rest API in BIDS 2008 using System.Net.WebRequest and without using newtonsoft. This is just a sample code and definitely can be fine tuned (well tested and it works and serves my test purpose like a charm). Its just to give you an Idea. I wanted this thread but couldn't find hence posting this.These were my major sources from where I pulled this. Link 1 and Link 2

Code that works(unit tested)

           //Get Example
            var httpWebRequest = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("https://abc.def.org/testAPI/api/TestFile");
            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Method = "GET";

            var username = "usernameForYourApi";
            var password = "passwordForYourApi";

            var bytes = Encoding.UTF8.GetBytes(username + ":" + password);
            httpWebRequest.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(bytes));
            var httpResponse = (System.Net.HttpWebResponse)httpWebRequest.GetResponse();
            using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                string result = streamReader.ReadToEnd();
                Dts.Events.FireInformation(3, "result from readng stream", result, "", 0, ref fireagain);
            }


            //Post Example
            var httpWebRequestPost = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("https://abc.def.org/testAPI/api/TestFile");
            httpWebRequestPost.ContentType = "application/json";
            httpWebRequestPost.Method = "POST";
            bytes = Encoding.UTF8.GetBytes(username + ":" + password);
            httpWebRequestPost.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(bytes));

            //POST DATA newtonsoft didnt worked with BIDS 2008 in this test package
            //json https://stackoverflow.com/questions/6201529/how-do-i-turn-a-c-sharp-object-into-a-json-string-in-net
            // fill File model with some test data
            CSharpComplexClass fileModel = new CSharpComplexClass();
            fileModel.CarrierID = 2;
            fileModel.InvoiceFileDate = DateTime.Now;
            fileModel.EntryMethodID = EntryMethod.Manual;
            fileModel.InvoiceFileStatusID = FileStatus.NeedsReview;
            fileModel.CreateUserID = "37f18f01-da45-4d7c-a586-97a0277440ef";
            string json = new JavaScriptSerializer().Serialize(fileModel);
            Dts.Events.FireInformation(3, "reached json", json, "", 0, ref fireagain);
            byte[] byteArray = Encoding.UTF8.GetBytes(json);
            httpWebRequestPost.ContentLength = byteArray.Length;
            // Get the request stream.  
            Stream dataStream = httpWebRequestPost.GetRequestStream();
            // Write the data to the request stream.  
            dataStream.Write(byteArray, 0, byteArray.Length);
            // Close the Stream object.  
            dataStream.Close();
            // Get the response.  
            WebResponse response = httpWebRequestPost.GetResponse();
            // Display the status.  
            //Console.WriteLine(((HttpWebResponse)response).StatusDescription);
            Dts.Events.FireInformation(3, "Display the status", ((HttpWebResponse)response).StatusDescription, "", 0, ref fireagain);
            // Get the stream containing content returned by the server.  
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.  
            StreamReader reader = new StreamReader(dataStream);
            // Read the content.  
            string responseFromServer = reader.ReadToEnd();
            Dts.Events.FireInformation(3, "responseFromServer ", responseFromServer, "", 0, ref fireagain);

References in my test script task inside BIDS 2008(having SP1 and 3.5 framework) enter image description here

Sandeep
  • 615
  • 6
  • 13