So, like me, you may have come across some incompatibility within your WebAPI client that means you can’t use .Net 4/4.5 (which is required to use HttpClient and HttpResponseMessage etc.) – or you’re writing a web service to fill in due to this incompatibility. This solution should allow you to access your API (using POST) from .Net 3.5 (and above, maybe even below).
First of all lets assume you have the following model (taken from ASP.NET):
class Product { public string Name { get; set; } public double Price { get; set; } public string Category { get; set; } }
Now usually you could access this using the following code (which will send a Product to be created):
HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://[address]/"); // Add an Accept header for JSON format. client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); // Create a new product var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" }; Uri gizmoUri = null; HttpResponseMessage response = client.PostAsJsonAsync("api/products", gizmo).Result; if (response.IsSuccessStatusCode) { gizmoUri = response.Headers.Location; } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); }
Lets say, however, that we simply want to post some request (which may have one or more request parameters of any type) that will return an object, in this case a Product. First of all we must create an object that will store this request (this class can be stored anywhere but personally I prefer to store in a file called JsonClasses.cs with all other request classes):
public class ProductRequest { public string Category { get; set; } }
Next we need a generic (literally) method that will allow us to post any type of request and return with any type of object (we know in advance what type of object will be returned). This method will make use of the .Net WebClient and Json.Net:
public static object postWebApi(object data, Uri webApiUrl) { // Create a WebClient to POST the request WebClient client = new WebClient(); // Set the header so it knows we are sending JSON client.Headers[HttpRequestHeader.ContentType] = "application/json"; // Serialise the data we are sending in to JSON string serialisedData = JsonConvert.SerializeObject(data); // Make the request var response = client.UploadString(webApiUrl, serialisedData); // Deserialise the response into a GUID return JsonConvert.DeserializeObject (response); }
Nothing needs to change within your web server application, other than including the ProductRequest class and adding code to deal with the request – but you probably already have that logic in place so it should just be a case of slightly modifying it. So next we just need to make the call:
// Create a ProductRequest for sending our request to our WebAPI ProductRequest productRequest = new ProductRequest(); productRequest.Category = "test"; Listproducts = postWebApi >(productRequest, new Uri("[url]"));
For completeness I have also included a GET request method:
public static object getWebApi(object data, Uri webApiUrl) { // Create a WebClient to GET the request WebClient client = new WebClient(); // Set the header so it knows we are sending JSON client.Headers[HttpRequestHeader.ContentType] = "application/json"; string queryString = ""; if (data != null) { // Separate the KeyValuePairs in to a query string foreach (var pair in data) { if (queryString.Length != 0) { queryString += "&"; } queryString += pair.Key + "=" + pair.Value; } } // Make the request var response = client.DownloadString(webApiUrl + "?" + queryString); // Deserialise the response into a GUID return JsonConvert.DeserializeObject (response); }
which can be used as below:
Product product = getWebApi>(null, new Uri("[url]")); // With no value
I hope this comes in helpful to someone, it took me a little while to work out as there was no existing whole solution that I could find – as usual if anyone has any questions please comment below.
10 replies on “How to access WebAPI from a .Net 3.5 client in C#”
It seems your code have some typos.
And… about query string – values for query string parameters should be encoded with Uri.EscapeDataString call.
and data can be either object but it should be accessed via reflection, or data should be IDictionary .
Hi Konstantin,
Thanks for pointing this out, I’ll try to correct when I get a chance – I usually copy and paste my working code where possible but sometimes need to make modifications and don’t always have time to test them.
Regarding why I haven’t encoded, if I recall correctly it was causing an issue on the other end but it was a while ago now. Obviously anyone using this code should use it as a starting point and modify as necessary to achieve what they really need.
Thanks again!
Can the above code works for .Net CF 3.5…?
Hi Sashi,
I’m not sure, I haven’t tested – but please give it a go and post the results here 🙂
Steve
I need to find the way to connect from 3.5 to a web api (this is a good option with 4.5) but I need 3.5
so THE TITLE IS WRONG
Hi Mario,
Sorry but you haven’t read the introduction carefully enough, this IS for 3.5.
Steve
Hey Stephen,
This is a great article,
When am using am getting the below error, can you help
– $exception {“The underlying connection was closed: An unexpected error occurred on a send.”} System.Net.WebException
– InnerException {“Received an unexpected EOF or 0 bytes from the transport stream.”} System.Exception {System.IO.IOException}
Hi Norbert,
Thanks for commenting and leaving feedback. It’s been a while since I’ve done any programming so not sure I’ll be much help – are you able to give any more infor? Do you know what line this occurs on? Have you looked around for the inner exception error? I wonder if maybe this is a security issue, are you using HTTPS and SSL or an older version of TLS as these are no longer supported; take a look here for more info: https://stackoverflow.com/questions/5382548/getting-eof-exception-over-https-call – you may wish to use TLS 1.2, but I’m not sure if this will be supported on your web server.
Steve
hi Stephen Pickett
i need to call api in framework 4.0 and tried this code and i have an exception “The underlying connection was closed: An unexpected error occurred on a send.”
and i write this line before call
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
and i have the exception
any help to solve this exception or another solution to solve it
Hi abanoub15halim,
If you are using 4.0 then I would suggest that you do not use my code, instead use the built in functionality e.g.
https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
Also I suggest you do not use SSL of any version as it is no longer secure, you want to be using TLS v1.2 or higher.
Best of luck,
Steve