0

I'm trying to write a simple REST service that I can talk to through my C# application. I want to send the REST service a JSON string and for it to send me a JSON string back. I want to do this using POST not GET as there is a fair amount of data that needs to be sent to it.. Also I would like to do it using what is built into the .net library that I'm using - .NET Framework 4.0.

So far I have the following code:

Client

        public void SendJSONPostRequest(string sFunction, string sJSON)
        {
            string sRequest = FormRequest(m_sWebServiceURL, sFunction, string.Empty);

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sRequest);
        request.Method = "POST";
        System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
        Byte[] byteArray = encoding.GetBytes(sJSON);
        request.ContentLength = byteArray.Length;
        request.ContentType = @"application/json";

        using (Stream dataStream = request.GetRequestStream())
        {
            dataStream.Write(byteArray, 0, byteArray.Length);
        }
        long length = 0;
        try
        {
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                length = response.ContentLength;
            }
        }
        catch (WebException ex)
        {
            // Log exception and throw as for GET example above
        }
}



public static string FormRequest(string sURL, string sFunction, string sParam)
        {
            StringBuilder sbRequest = new StringBuilder();
            sbRequest.Append(sURL);
            if (!sURL.EndsWith("/"))
            {
                sbRequest.Append("/");
            }
            sbRequest.Append(sFunction);

            if ((!sFunction.EndsWith("/") && 
                (!string.IsNullOrEmpty(sParam))))
            {
                sbRequest.Append("/");
            }
            sbRequest.Append(sParam);

            return sbRequest.ToString();
        }

Server

using System;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Activation;
using System.IO;

namespace ExampleRESTService
{
    [ServiceContract(Name = "RESTServices")]
    public interface IRESTServices
    {    
        [OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = Routing.Route, BodyStyle = WebMessageBodyStyle.Bare)]
        string GetCounts();
    }

    public static class Routing
    {            
        public const string Route = "/GetCounts";
    }

   [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single, IncludeExceptionDetailInFaults = true)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class RESTServices : IRESTServices
    {
        public string GetCounts()
        {
            string sData = "Hello"
            return sData;
        }
    }
}

Now this isn't all of the code but it is the bits that are important I think. Also I've changed names for display online but it all compiles so please ignore if a typo. Apologies if there is something significant.

The REST service can be called from my client fine as is but my question is...

How do I extract the data in my REST service GetCounts() method that was posted to it from the client, i.e the JSON string?

Thanks in advance.

Yos
  • 383
  • 1
  • 6
  • 24
  • 4
    This looks like WCF. If you're just trying to write a simple REST service, why not use WebAPI? [Here's a link to an SO resource that you might be interested in.](https://stackoverflow.com/questions/9348639/wcf-vs-asp-net-web-api) – Joshua Shearer Jan 22 '16 at 21:10
  • `var data = (new StreamReader(Request.InputStream)).ReadToEnd();` or something – Alexandru Jan 22 '16 at 21:13
  • 1
    I think what you are looking for is `GetCounts(Someobject data)` just define the class for the `Someobject` – Omar Martinez Jan 22 '16 at 21:18
  • 1
    Hi Thanks. Should I be changing to public string GetCounts([FromBody] string data) If so how should my request be from the client? If it was previously: http://localhost:8000/ExampleRESTService/GetCounts Do I now need a parameter? http://localhost:8000/ExampleRESTService/GetCounts/data (really long) – Yos Jan 22 '16 at 21:39
  • 1
    If you are doing [FromBody] you don't need a parameter, the url is whatever your Route is set to. – Cleverguy25 Jan 22 '16 at 22:48
  • Hi Cleverguy25. Thanks for this. However it doesn't work.. The same URL does work if I test in Chromes POSTER but in my C# Client it gives me the following exception: {System.Net.WebException: The remote server returned an error: (400) Bad Request. at System.Net.HttpWebRequest.GetResponse() Do you have any ideas why this might be? Thanks – Yos Jan 22 '16 at 22:57
  • In fact it seems to work if I don't post any data strangely! – Yos Jan 22 '16 at 23:26

1 Answers1

0

The response is returned as a stream.

I think you will find that the answer is in this link

How to convert WebResponse.GetResponseStream return into a string?

The sample there which I have used myself plenty of times is as follows

using (Stream stream = response.GetResponseStream())
{
   StreamReader reader = new StreamReader(stream, Encoding.UTF8);
   String responseString = reader.ReadToEnd();
}

if you then want to convert the JSON into a class for easier manipulation then Newtonsoft have a library to serialize and Deserialize to transfer between both.

Community
  • 1
  • 1
Paul S Chapman
  • 832
  • 10
  • 37
  • 1
    I may be wrong, but it seemed to me like the question was referring to how to access the `POST` data on the server. – Joshua Shearer Jan 22 '16 at 21:12
  • Hi Thanks, This is really useful and I will use this but for now I need to be able to extract the data in the Web Service Server GetCounts method that I originally POSTed to it? – Yos Jan 22 '16 at 21:40