I have executed RestRequest and got non-typed IRestResponse.
How can I convert it to IRestResponse<T>?
For example IRestResponse<MyErrorData> or IRestResponse<MyData>?
You need to use the generic overload of Execute:
var client = new RestClient();
client.BaseUrl = BaseUrl;
request.AddParameter("AccountSid", _accountSid, ParameterType.UrlSegment);
var response = client.Execute<T>(request);
Execute<T> is the key to getting back a typed response.
I found that, depending on the version of RestSharp you have installed, Execute<T> threw a compiler error. (Tho it seems fine in v106.15.)
Another option is to cast it, which seems to work when the first option doesn't:
RestClient client = new RestClient();
IRestResponse<T> response = (IRestResponse<T>)client.Execute(request);
Also, don't forget that your method (or class) must be decorated with the T type parameter:
Eg
partial void InterceptResponse<T>(IRestRequest request, ref IRestResponse<T> response)
...
RestClient client = new RestClient();
IRestResponse<T> response = client.Execute<T>(request);
(or IRestResponse<T> response = (IRestResponse<T>)client.Execute(request);)
....
(In this example, I'm intercepting a RestResponse, doing something, such as re-calling, and passing back the new response as ref response.)
Related
Im using this line to consume the API post method
var postTask = client.PostAsJsonAsync("AgregarNegocio", new StringContent(JsonConvert.SerializeObject(model).ToString(), Encoding.UTF8, "application/json"));
however when the API method is hit
public IActionResult AgregarNegocio([FromBody]NegocioViewModel model)
all the properties in model are null...
i already tried with and without [FromBody] and other solutions but none has worked yet, any suggestions?, thanks!
You need to construct your http client like this:
_client = new HttpClient { BaseAddress = new Uri("your http://my base url goes here"),
Timeout = new TimeSpan(0, 0, 0, 0, -1) };
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));//add json header
//_client.DefaultRequestHeaders.Add("Bearer", "some token goes here");
and you need to call your method like this:
var postTask = await _client.PostAsJsonAsync("AgregarNegocio", model);
make sure you call "await" on it because it is async.
NOTES:
Notice that I added MediaTypeWithQualityHeaderValue to indicate that it is json.
Also using Route usually is not a good idea... It is better to use HttPost("MyRoute") because it combined the ControllerName + Route. But it is up to you.
Try to use PostAsync instead of PostAsJsonAsync
var postTask = await client.PostAsync("AgregarNegocio", new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"));
You can use the HttpClient extension method :
https://learn.microsoft.com/en-us/previous-versions/aspnet/hh944682(v=vs.118)
PostAsJsonAsync(
this HttpClient client,
string requestUri,
T value
)
var postTask = client.PostAsJsonAsync<NegocioViewModel>("AgregarNegocio", model);
You can use PostAsync but also do not forget about using HttpClient in right way as i described in this article.
I'm trying to POST a request containing JSON from a Razor Pages app to a WCF service endpoint expecting a Json WebMessageFormat and Bare BodyStyle.The JSON passes just fine via Postman, but not when I send it through http-client. Wireshark also shows some extra bytes around JSON in the http-client produced packet that are not present in the Postman packet. Wireshark also reports this as line-based text data: application/json for the Postman packet. The .Net packet is JavaScript Object Notation: application/json.
Here's my C# code to send the JSON to the WCF endpoint:
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:8000");
dynamic foo = new ExpandoObject();
foo.position = 1;
var content = new StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(foo), System.Text.Encoding.UTF8, "application/json");
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:8000/WCFService/ControllerV1/PostJSON");
request.Headers.Add("cache-control", "no-cache");
request.Headers.Add("Accept", "*/*");
request.Headers.Add("Connection", "keep-alive");
request.Content = content;
try
{
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
}
catch (HttpRequestException e)
{
Console.WriteLine(e.Message);
}
And here's my WCF endpoint declaration:
[OperationContract, WebInvoke(Method="POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
void PostJSON(string jsonString);
I would expect the packets to produce the same response from the server, but, what appears to be the same string produces a response 200 when the packet is built by postman and a response 400 when built by .Net. I'm clearly missing something subtle here, but I can't seem to tease it out.
There are 2 possible BodyStyle for request and response, wrapped or bare. When you specify wrapped body style the WCF service expects a valid json to be passed which in your case would be
//note that property name is case sensitive and must match service parameter name
{
"jsonString": "some value"
}
And when you specify bare format the service expects only plain string value (in case of primitive type as yours) as the request like this
"some value"
When you serialize your object like this
dynamic foo = new ExpandoObject();
foo.position = 1;
string result = JsonConvert.SerializeObject(foo);
the result contains the following json
{
"position":1
}
which corresponds to wrapped format and the service returns 400: Bad Request. All you need to do is to turn this json into valid json string value like this
"{\"position\":1}"
It can be done by repeated JsonConvert.SerializeObject call
dynamic foo = new ExpandoObject();
foo.position = 1;
string wrapped = JsonConvert.SerializeObject(foo);
string bare = JsonConvert.SerializeObject(wrapped);
var content = new StringContent(bare, System.Text.Encoding.UTF8, "application/json");
I'm using HttpClient like this in my console app:
using (var http = new HttpClient(handler))
{
http.BaseAddress = new Uri("http://127.0.0.1:34323/");
var response = await http.PostAsync("/api/generate", new StringContent(
JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"));
Console.WriteLine(response.Content.ToString());
}
In debug mode, I can see that the controller is returning a string of JSON.
However, I only get this written to the console:
System.Net.Http.StreamContent
How can I get it to write the actual JSON that's being returned?
Thanks!
Try below line:
Console.WriteLine(response.Content.ReadAsStringAsync().Result.ToString());
I have this bunch of code. First is a test class method testEndPoint(), I have also included the class to be tested EndPointClass.
When I run this testmethod, it tries to run the actual send http Call method instead of mocking or a dummy call, hence it gives a 500 not found error.
I know somewhere the code needs to be corrected not sure where.
Here's the code
public void testEndPoint(){
OutputObject output = new OutputObject();
EndPointClass epClass = new EndPointClass();
EndPointClass epClassSpy = Mockito.spy(epClass);
List<JacksonJsonProvider> providers = new ArrayList<JacksonJsonProvider>();
providers.add(mockCustomJacksonProvider);
WebClient client = WebClient.create("http://example.org/home",providers);
WebClientWrapper webClientWrapper = new WebClientWrapper(client);
WebClientWrapper spyWebClient = Mockito.spy(webClientWrapper);
Mockito.when(spyWebClient.invoke(Mockito.any(String.class),Mockito.any(Object.class),Mockito.eq(OutputObject.class))).thenReturn(output);
Mockito.when(epClassSpy.webCall(spyWebClient)).thenReturn(output);
OutputObject response = epClassSpy.sendRequest("ABC", "ABCToken");
}
public class EndPointClass{
public OutputObject sendRequest(String input, String authToken){
List<JacksonJsonProvider> providers = new ArrayList<JacksonJsonProvider>();
providers.add(downloadsJacksonProvider);
WebClient client = WebClient.create(olsDownloadUrl+path, providers);
if (null == timeOut) {
timeOut = 60000;
}
HTTPConduit http = (HTTPConduit) WebClient.getConfig(client).getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(0);
httpClientPolicy.setReceiveTimeout(timeOut);
http.setClient(httpClientPolicy);
client.type("application/json");
client.accept("application/json");
client.header("x-auth-Token", authToken);
client.query("input", input);
OutputObject output = null;
WebClientWrapper clientWrapper = new WebClientWrapper(client);
output = webCall(clientWrapper);
return output;
}
public OutputObject webCall(WebClientWrapper clientWrapper) {
return clientWrapper.invoke(HttpMethod.GET, null, OutputObject.class);
}
}
From the official documentation
Important gotcha on spying real objects!
Sometimes it's impossible or impractical to use when(Object) for stubbing spies. Therefore when using spies please consider doReturn|Answer|Throw() family of methods for stubbing. Example:
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws ndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
So just change your Mockito.when(...) to Mockito.doReturn(...) that should do the trick.
I am trying to query my local Solr server using HttpClient and I cannot figure out why the parameters are not being added to the GET call.
My code for doing this is:
HttpRequestBase request = new HttpGet("http://localhost:8080/solr/select");
HttpParams params = new BasicHttpParams();
params.setParameter("q", query);
params.setParameter("start", String.valueOf(start));
params.setParameter("rows", String.valueOf(rows));
request.setParams(params);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
return stringToStreamConversion(is); //500 error, NullPointerException, response is empty
I have tried to return several things in hopes of seeing what I would get and trying to figure out where the problem was. I have finally realized that I was only getting back the http://localhost:8080/solr/select when I returned
return request.getURI().toURL().toString();
I cannot figure out why the parameters are not getting added. If I do
return request.getQuery();
I get nothing back...any ideas? Thanks for the help in advance!
From what I have seen you are not able to associate your paeans with the request.
So, instead of creating a new HttpParams object and associating it with request, can you try the following approach ?
httpCclient.getParams().setParameter("q", query");
....
The simpler option is to use the approach I used in HTTPPostScheduler, like this:
URL url = new URL(completeUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("type", "submit");
conn.setDoOutput(true);
// Send HTTP POST
conn.connect();