How to call the PUT method from Web Api using HttpClient?

I want to call the Api function (1st). from 2nd Api function using HttpClient . But I always get 404 Error.

1st Api function ( EndPoint: http: // localhost: xxxxx / api / Test /)

public HttpResponseMessage Put(int id, int accountId, byte[] content) [...] 

Second Api Function

 public HttpResponseMessage Put(int id, int aid, byte[] filecontent) { WebRequestHandler handler = new WebRequestHandler() { AllowAutoRedirect = false, UseProxy = false }; using (HttpClient client = new HttpClient(handler)) { client.BaseAddress = new Uri("http://localhost:xxxxx/"); // Add an Accept header for JSON format. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var param = new object[6]; param[0] = id; param[1] = "/"; param[2] = "?aid="; param[3] = aid; param[4] = "&content="; param[5] = filecontent; using (HttpResponseMessage response = client.PutAsJsonAsync("api/Test/", param).Result) { return response.EnsureSuccessStatusCode(); } } } 

So my question is that. Can I publish a method parameter as an array of objects from HttpClient, just like me? I do not want to pass the model as a parameter to a method.

What happened in my code?

Unable to get any response after changing code

 return client.PutAsJsonAsync(uri, filecontent) .ContinueWith<HttpResponseMessage> ( task => task.Result.EnsureSuccessStatusCode() ); 

OR

 return client.PutAsJsonAsync(uri, filecontent) .ContinueWith ( task => task.Result.EnsureSuccessStatusCode() ); 
+6
source share
1 answer

As you probably learned, you cannot. When you call PostAsJsonAsync , the code converts the parameter to JSON and sends it to the request body. Your parameter is a JSON array that will look something like this:

 [1,"/","?aid",345,"&content=","aGVsbG8gd29ybGQ="] 

This is not what the first function expects (at least, what I imagine, since you did not provide route information). There are several issues here:

  • By default, parameters of type byte[] (reference types) are passed in the request body, and not in the URI (unless you explicitly mark the parameter with the [FromUri] attribute).
  • Other parameters (again, based on my assumption about your route) should be part of the URI, not the body.

The code looks something like this:

 var uri = "api/Test/" + id + "/?aid=" + aid; using (HttpResponseMessage response = client.PutAsJsonAsync(uri, filecontent).Result) { return response.EnsureSuccessStatusCode(); } 

Now there is another potential problem with the code above. It waits for a network response (what happens when accessing the .Result property in the Task<HttpResponseMessage> returned by PostAsJsonAsync . Depending on the environment, it can worse happen that it can be deadlocked (waiting in the thread for a network response to respond). In the best case, this the thread will be blocked for the duration of the network call, which is also bad. Consider using asynchronous mode (waiting for the result, returning the Task<T> in your action) instead, as in the example below

 public async Task<HttpResponseMessage> Put(int id, int aid, byte[] filecontent) { // ... var uri = "api/Test/" + id + "/?aid=" + aid; HttpResponseMessage response = await client.PutAsJsonAsync(uri, filecontent); return response.EnsureSuccessStatusCode(); } 

Or without the async / wait keywords:

 public Task<HttpResponseMessage> Put(int id, int aid, byte[] filecontent) { // ... var uri = "api/Test/" + id + "/?aid=" + aid; return client.PutAsJsonAsync(uri, filecontent).ContinueWith<HttpResponseMessage>( task => task.Result.EnsureSuccessStatusCode()); } 
+7
source

All Articles