How to POST custom object to web api using C# - c#

I have a web api developed and deployed. It works with unit test and using fiddler. However, if i create a separate project and try to post data to it, it sends back a 400 Bad Request error. I am looking for a way to post this custom object using a client being written in C#. Unlike WCF there is no matadata to create proxy of these objects from and then instantiate and pass it on to calling methods. How do you pass a custom object like Customer as a parameter to a method?
URL would be http://host/directory/api/customer/AddNewCustomer
and method definition is like
[HttpPost]
public bool AddNewCustomer(Customer customerObj)
EDIT
Following is my client code
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://host/directory/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.Timeout = TimeSpan.FromSeconds(30.0);
// strong typed instance
var values = new JObject();
values.Add("FirstName", "John");
values.Add("LastName", "Doe");
HttpContent content = new StringContent(values.ToString(), Encoding.UTF8,"application/json");
var response = client.PostAsJsonAsync("api/customer/AddNewCustomer", content).Result;

After trying many solutions, usign fiddler i came to know that content object was not set. This is strange but that was the case. So i tried passing JObject directly wihout casting it to HttpContent and it worked
// strong typed instance
var values = new JObject();
values.Add("FirstName", "John");
values.Add("LastName", "Doe");
// this is not set!!!
HttpContent content = new StringContent(values.ToString(), Encoding.UTF8,"application/json");
var response = client.PostAsJsonAsync("api/customer/AddNewCustomer", values).Result;

Ideally Customer would be in a separate class library of models and you could share that dll between projects. But any object with the same property names will work because web API will serialized them to Json or xml and make the mappings automatically.

Related

C# http request add json object in the content

I'm making an http request post to an external api. I am constructing a json object to add to the request body. How can I check if the added body/content is correct before it is sent.
public async void TestAuthentication()
{
var client = new HttpClient();
var request = new HttpRequestMessage()
{
RequestUri = new Uri("http://test"),
Method = HttpMethod.Post
};
var jsonObj = new
{
data = "eneAZDnJP/5B6r/X6RyAlP3J",
};
request.Content = new StringContent(JsonConvert.SerializeObject(jsonObj), Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
}
If you are not sure whether the serialization works as intended, you could give it a shot in LINQpad or dotnetfiddle.net. See my example that returns the JSON on the console. These tools are great for quick prototyping a method or a snippet, if you are not sure if a piece of code works as intended.
You could also check in Wireshark, but that could be a bit of an overkill and works best if your connection if not encrypted (no HTTPS).
I personally tend to test code that calls some API the following way:
Make the called URL parameterizable (via the classes constructor)
If there is any variable data this data should be passed as the methods parameter(s)
For your test start an HTTP server from your test fixture (read on testing with xUnit or NUnit if you don't know what this means)
I use PeanutButter.SimpleHTTPServer for that
Pass the local IP to the class that accesses the API
Check whether the HTTP server received the expected data
Whether or not this kind of code shall be tested (this way) may be debatable, but I found this way to work kind of good. I used to abstract the HttpClient class away, but IMHO I would not recommend this anymore, because if the class accesses the API (and does not do anything else, which is important), the HTTP access is the crucial part that shall be tested and not mocked.

Adding Session Request To API Call

I'm unsure how to add the Session Request to the API call as per the Food Hygiene Instructions. I've copied the relevant code and hope I am close, but unsure where to put this one part.
Reference: https://api.ratings.food.gov.uk/help
Need to add into the API call: Session.Request.Headers.Add("x-api-version", 2);
Partial Code:
readonly string Baseurl = "https://api.ratings.food.gov.uk";
public async Task<ActionResult> Index()
{
List<Authorities> AuthInfo = new List<Authorities>();
using var client = new HttpClient
{
//Passing service base url
BaseAddress = new Uri(Baseurl)
};
client.DefaultRequestHeaders.Clear();
//Define request data format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
***//Session.Request.Headers.Add("x-api-version", 2);***
//Sending request to find web api REST service resource GETRegions using HttpClient
HttpResponseMessage Res = await client.GetAsync("Authorities/basic");
The documentation you're referring to is misleading/incorrect. When you talk about Session (at least in the .NET world) you talk about the server-side. You're obviously a client of the API, rather than a developer of it, so they asking you to put stuff in the Session is incorrect.
You're a client, passing headers in your requests, so it's just:
client.DefaultRequestHeaders.Add("x-api-version", "2");
Side note, you may want to reuse that HttpClient instance if you are going to make that call often.
Side note 2: you may want to ask them to fix the docs :)

Read GRPC headers

I'm sending data via GRPC to, let's call it, IntegrationApi, calling a method Foo. I need to read header values from the response (the API I'm communicating with sends rate-limiting headers).
I'm using https://www.nuget.org/packages/Grpc.Core/
var metaData = new Metadata();
metadata.Add(new Metadata.Entry("Authorization", $"Bearer {apiKey}"));
var channel = new Channel("url to endpoint", new SslCredentials());
var client = new IntegrationApi(channel);
var callOptions = new CallOptions()
.WithHeaders(metadata)
.WithDeadline(DateTime.UtcNow.AddSeconds(15))
.WithWaitForReady(false);
var response = client.Foo(req, options);
but the response only gives me the properties based on the Foo.proto file.
How do I do this?
You are using the synchronous version of "Foo" method, and that one uses a simplified version of the API (=only allows access to the response and throws RpcExceptions in case of an error).
If you call the asynchronous version of the same method ("FooAsync"), you'll get back a call object that can access all the call details (such as response headers).
https://github.com/grpc/grpc/blob/044a8e29df4c5c2716c7e8250c6b2585e1c425ff/src/csharp/Grpc.Core.Api/AsyncUnaryCall.cs#L73

Http Put and querystring

I have two problems. I am trying to interact with a Web API that is wanting a HTTP PUT. I am trying to pass the parameters as part of the querystring. Unfortunately, I am not really sure how to do that. Do I include them in with the first parameter of the PutAsync method as shown below?
The other question I have is I am unsure what needs to be coded for the HTTPContent object when using the PutAsync method. I am trying to pass the parameters in the querystring instead of other methods that might be used. Most of the examples that I can find are passing the data as json.
using (var apiManagementSystem = new HttpClient())
{
apiManagementSystem.BaseAddress = new Uri("https://thedomain.com/api/");
apiManagementSystem.DefaultRequestHeaders.Clear();
apiManagementSystem.DefaultRequestHeaders.Add("SessionID", _sessionID);
HttpContent httpContent = new /* What do I do Here? */
responseMessage = apiManagementSystem.PutAsync("Product/someID?available=N", httpContent).Result;
}
My finished url should be something like this.
https://thedomain.com/api/Product/someID?available=N
This API that I am communicating with is a Rest API

Modify request headers per request C# HttpClient PCL

I'm currently using the System.Net.Http.HttpClient for cross platform support.
I read that it is not a good practice to instantiate a HttpClient object for each request and that you should reuse it whenever possible.
Now I have a problem while writing a client library for a service. Some API calls need to have a specific header, some MUST not include this specific header.
It seems that I can only manipulate the "DefaultRequestHeaders" which will be send with each request.
Is there an option when actually making the request with e.g. "client.PostAsync()" to modify the headers only for the specific request?
(Info: Requests can be multi threaded).
Thanks in advance!
Yes, you can create a new HttpRequestMessage, set all the properties you need to, and then pass it to SendAsync.
var request = new HttpRequestMessage() {
RequestUri = new Uri("http://example.org"),
Method = HttpMethod.Post,
Content = new StringContent("Here is my content")
}
request.Headers.Accept.Add(...); // Set whatever headers you need to
var response = await client.SendAsync(request);
Use HttpContent.Headers. Simply create HttpContent instance with required headers and pass it to PostAsync method.

Categories