CraigJSte
CraigJSte

Reputation: 932

C# Web API Sending Body Data in HTTP Post REST Client

I need to send this HTTP Post Request:

 POST https://webapi.com/baseurl/login
 Content-Type: application/json

 {"Password":"password",
 "AppVersion":"1",
 "AppComments":"",
 "UserName":"username",
 "AppKey":"dakey" 
  }

It works great in RestClient and PostMan just like above.

I need to have this pro-grammatically and am not sure if to use

WebClient, HTTPRequest or WebRequest to accomplish this.

The problem is how to format the Body Content and send it above with the request.

Here is where I am with example code for WebClient...

  private static void Main(string[] args)
    {
        RunPostAsync();
    } 

    static HttpClient client = new HttpClient();

    private static void RunPostAsync(){

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));

            Inputs inputs = new Inputs();

            inputs.Password = "pw";
            inputs.AppVersion = "apv";
            inputs.AppComments = "apc";
            inputs.UserName = "user";
            inputs.AppKey = "apk";


            var res = client.PostAsync("https://baseuriplus", new StringContent(JsonConvert.SerializeObject(inputs)));

            try
            {
                res.Result.EnsureSuccessStatusCode();

                Console.WriteLine("Response " + res.Result.Content.ReadAsStringAsync().Result + Environment.NewLine);

            }
            catch (Exception ex)
            {
                Console.WriteLine("Error " + res + " Error " + 
                ex.ToString());
            }

        Console.WriteLine("Response: {0}", result);
    }       

    public class Inputs
    {
        public string Password;
        public string AppVersion;
        public string AppComments;
        public string UserName;
        public string AppKey;
    }

This DOES NOW WORK and responses with a (200) OK Server and Response

Upvotes: 11

Views: 88700

Answers (5)

Hassan Faghihi
Hassan Faghihi

Reputation: 2039

I made a tools to do it quick and easy:

Install-Package AdvancedRestHandler

or

dotnet add package AdvancedRestHandler
AdvancedRestHandler arh = new AdvancedRestHandler("https://webapi.com/baseurl");
var result = await arh.PostDataAsync<MyLoginResponse, MyLoginRequest>("/login", new MyLoginRequest{
  Password = "password",
  AppVersion = "1",
  AppComments = "",
  UserName = "username",
  AppKey = "dakey"
});

public class MyLoginRequest{
  public string Password{get;set;}
  public string AppVersion{get;set;}
  public string AppComments{get;set;}
  public string UserName{get;set;}
  public string AppKey{get;set;}
}

public class MyLoginResponse {
  public string Token{get;set;}
}

Extra:

One other thing you can do is to use ArhResponse:

  • Either this way, in the class definition:
public class MyLoginResponse: ArhResponse 
{
...
}
  • Or this way, in the API call:
var result = await arh.PostDataAsync<ArhResponse<MyLoginResponse>, MyLoginRequest> (...)

and instead of try or cache, check your API call state using simple if statements:

// check service response status:
if(result.ResponseStatusCode == HttpStatusCode.OK) { /* api receive success response data */ }

// check Exceptions that may occur due to implementation change, or model errors
if(result.Exception!=null) { /* mostly serializer failed due to model mismatch */ }

// have a copy of request and response, in case the service provider need your request response and they think you are hand writing the service and believe you are wrong
_logger.Warning(result.ResponseText);
_logger.Warning(result.RequestText);

// Get deserialized verion of, one of the fallback models, in case the provider uses more than one type of data in same property of the model
var fallbackData = (MyFallbackResponse)result.FallbackModel;

Header Possible Issue

There are cases that the Server does not accept C# request due to the header that the HttpClient generates.

It is because HttpClient by default uses the value of application/json; charset=utf-8 for Content-Type...

For sending only application/json part as Content-Type and ignore the ; charset=utf-8 part, you can do as following:

For HttpClient you can fix it by looking into this thread: How do you set the Content-Type header for an HttpClient request?

As for (AdvancedRestHandler) ARH, I fixed it due to integration with some company, but I don't remember fully... I did it, either through options like of requests or through resetting the header value.

Upvotes: 0

Ya Wang
Ya Wang

Reputation: 1808

Why are you generating you own json?

Use JSONConvert from JsonNewtonsoft.

Your json object string values need " " quotes and ,

I'd use http client for Posting, not webclient.

using (var client = new HttpClient())
{
   var res = client.PostAsync("YOUR URL", 
     new StringContent(JsonConvert.SerializeObject(
       new { OBJECT DEF HERE },
       Encoding.UTF8, "application/json")
   );

   try
   {
      res.Result.EnsureSuccessStatusCode();
   } 
   catch (Exception e)
   {
     Console.WriteLine(e.ToString());
   }
}   

Upvotes: 13

Dev-lop-er
Dev-lop-er

Reputation: 728

            var client = new RestClient("Your URL");
            var request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/json");
            request.AddHeader("apk-key", apk);

            //Serialize to JSON body.
            JObject jObjectbody = new JObject();
            jObjectbody.Add("employeeName", data.name);
            jObjectbody.Add("designation", data.designation);

            request.AddParameter("application/json", jObjectbody, ParameterType.RequestBody);

            try
            {
                var clientValue= client.Execute<Response>(request);
                return RequestResponse<Response>.Create(ResponseCode.OK, "", clientValue.Data);
            }
            catch (Exception exception)
            {
                throw exception;
            }

Upvotes: 1

Papun Sahoo
Papun Sahoo

Reputation: 428

we will use HttpPost with HttpClient PostAsync for the issue.

using System.Net.Http;
    static async Task<string> PostURI(Uri u, HttpContent c)
    {
    var response = string.Empty;
    using (var client = new HttpClient())
    {
    HttpResponseMessage result = await client.PostAsync(u, c);
    if (result.IsSuccessStatusCode)
    {
    response = result.StatusCode.ToString();
    }
    }
    return response;
    }

We will call it by creating a string that we will use to post:

  Uri u = new Uri("http://localhost:31404/Api/Customers");
        var payload = "{\"CustomerId\": 5,\"CustomerName\": \"Pepsi\"}";

        HttpContent c = new StringContent(payload, Encoding.UTF8, "application/json");
        var t = Task.Run(() => PostURI(u, c));
        t.Wait();

        Console.WriteLine(t.Result);
        Console.ReadLine();

Upvotes: -2

Jonathon Chase
Jonathon Chase

Reputation: 9704

You are not properly serializing your values to JSON before sending. Instead of trying to build the string yourself, you should use a library like JSON.Net.

You could get the correct string doing something like this:

var message = JsonConvert.SerializeObject(new {Password = pw, AppVersion = apv, AppComments = acm, UserName = user, AppKey = apk});
Console.WriteLine(message); //Output: {"Password":"password","AppVersion":"10","AppComments":"","UserName":"username","AppKey":"dakey"}

Upvotes: 2

Related Questions