DEV Community

Chris Cooper
Chris Cooper

Posted on • Updated on • Originally published at coopsblog.wales

Sending Data Objects to WebAPI in C#

Alt text of image

This is a easy and reusable code that can be used to send data object to WebAPIs in C#. This code is an improvement to the code already posted on my blog.

This now will work with Get and parameter webAPI action methods and you want to use data class on your side. The object will need parameters with the same name as the parameters of the API

Invoking
This is the main method that would invoke the API logic. This needs the API full URL, API HTTP action type (GET/POST), return object type

public class JSONAPI 
{

    public static object Invoke(string url, string requestMethod, object dataObject, Type returnType)
    {
        object returnObject = null;

        callAPI(url, requestMethod, dataObject, returnType, updateStatus,  ref returnObject);

        return returnObject;
    }

}

Calling the API
This is the main method that takes the parameter and return object

    private static void callAPI(string url, string requestMethod, object dataObject,Type returnType, ref object returnObject)
    {

        try
        {

            HttpWebRequest request = null;
            FoundServices = true;

            createRequest(url, requestMethod, dataObject, ref request);

            if (request != null)
            {

                WebResponse webResponse = null;

                if (getReponse(request,updateStatus,  ref webResponse))
                {
                    updateStatus(SyncServiceTextResource.JSONDataDownloading, 0, ENUMS.MainProgressENUM.UpdateSecondary);

                    Stream webStream = webResponse.GetResponseStream();
                    using (StreamReader reader = new StreamReader(webStream))
                    {
                        using (var json = new Newtonsoft.Json.JsonTextReader(reader))
                        {
                            Newtonsoft.Json.JsonSerializer serializerJ = new Newtonsoft.Json.JsonSerializer();
                            updateStatus(SyncServiceTextResource.JSONDataConverting, 0, ENUMS.MainProgressENUM.UpdateSecondary);
                            returnObject = serializerJ.Deserialize(json, returnType);
                            updateStatus(SyncServiceTextResource.JSONDataConvertingCompleted, 0, ENUMS.MainProgressENUM.UpdateSecondary);
                            System.GC.Collect();
                        }//END using (var json = new Newtonsoft.Json.JsonTextReader(reader))
                    }//END using (StreamReader reader = new StreamReader(webStream))
                }//END if (getReponse(request,updateStatus,  ref webResponse))
            }//END if (request != null)

        }
        catch (Exception e)
        {

        }

    }

Create the request
This is the method is used to take the parameter object and the GET OR POST type, with the URL to create the the required string to call the API.

     private static bool createRequest(string url, string requestMethod, object dataObject, ref HttpWebRequest request)
    {
        request = null;


        request = (HttpWebRequest)WebRequest.Create(url);

        request.Method = requestMethod;// "POST";
        request.ContentType = "application/json";
        string jsonDataString = setJSONString(dataObject);

        if (dataObject != null && requestMethod.Equals("POST"))
        {

            request.ContentLength = jsonDataString.Length;
            request.Method = requestMethod;// "POST";
            request.ContentType = "application/json";
            //request.SendChunked = true;



            StreamWriter requestWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);

            requestWriter.Write(jsonDataString);
            requestWriter.Close();
        }
        else
        {
            var jObj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(jsonDataString);
            var query = String.Join("&",
                            jObj.Children().Cast()
                            .Select(jp => jp.Name + "=" + HttpUtility.UrlEncode(jp.Value.ToString())));


            bool parameters = true;

            if (!parameters)
                url += "?" + jsonDataString;
            else
                url += "?" + query;


            request = (HttpWebRequest)WebRequest.Create(url);// +"?"+ query);


            request.Method = requestMethod;// "POST";
            request.ContentType = "application/json";


        }


        return request.HaveResponse;


    }

Json string creation
This method takes the object and creates a JString for the object

    private static string setJSONString(object dataObject)
    {
        var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
        serializer.MaxJsonLength = MAXJSONLENGTH;
        string jsonDataString = serializer.Serialize(dataObject);
        return jsonDataString;
    }

Get response
This method will wait an x amount of time to make sure it has given the API enough time to response.

     private  static bool getReponse(HttpWebRequest request, ref WebResponse response)
    {
        bool responseCompleted = false;                       
        System.Timers.Timer tim = new System.Timers.Timer();
        tim.Interval = 2000;       
        timerElapsed = false;
        tim.Start();

        int milSeconWait = 500;//Start with 0.5 seconds wait
        int maxMilSeconWait = 120000;//MAX of 2 Mins
        int timesWaiting = 0;
        bool stillWaiting = false;
        while (!responseCompleted)
        {

            if (timerElapsed)
            {
               responseCompleted = false;
                break;
            }
            responseCompleted = webResponse.IsCompleted;
            if (responseCompleted)
            {
                break;
            }    
           timesWaiting++;

            Console.WriteLine("JSON GET REPSONE SLEEP AND WAIT: " + milSeconWait.ToString() + " Wait loop " + timesWaiting.ToString());
            System.Threading.Thread.Sleep(milSeconWait);
            milSeconWait = INITIALWAIT * timesWaiting;
        }

        if (responseCompleted && webResponse.Result != null)
        {
            response = webResponse.Result;

        }
        tim.Stop();
        tim.Dispose();
        timerElapsed = false;          

        return responseCompleted;
    }

Constant used
Below are the constants used through the full logic code

    private const int MAXJSONLENGTH = int.MaxValue;
    protected static bool FoundServices;
    private static bool timerElapsed = false;
    private static bool secondAttempt;
    private const int INITIALWAIT = 500;//MIN 0.5 second wait

WebAPI Get Action side
To make sure the API will work with the above code will need the [FromUri] in the method call.

public class SIMPLEController : ApiController
{

    [HttpGet]        
    public DataClasses.Returns.OBJECTCLASS GET([FromUri]DataClasses.Parameters.OBJECTCLASS parameter)
    {
        var watch = System.Diagnostics.Stopwatch.StartNew();

        DataClasses.Returns.OBJECTCLASS  returnObject new DataClasses.Returns.OBJECTCLASS ();

        //DO LOGIC

        return returnObject;
    }
}

Top comments (0)