I am having a problem when I try using a rest web service in C#.
When I try via Fiddler it works Ok.
When I try via HTML/Ajax, it works Ok, as well.
When I try via C# (Console Application) I get an error.
This image is captured in fiddler. It is what I get when I try via ajax
this image is also captured in fiddler. It is what I get when I try via C#
As you can see, the JSON field is empty.
This is my C# code
string json = JsonConvert.SerializeObject(abc);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("MyURL"); //==> I am filling it correctly
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.PostAsJsonAsync("MyMethod", json).Result; //==> I am filling my method correctly
But I have tried several others and always getting the same problem. (the code bellow is another one I tried)
var requisicaoWeb = WebRequest.CreateHttp("MyURL");
requisicaoWeb.Method = "POST";
requisicaoWeb.ContentType = "application/json";
requisicaoWeb.ContentLength = dados.Length;
requisicaoWeb.UserAgent = "Console app";
requisicaoWeb.Accept = "Accept:application/json,text/javascript,*/*;q=0.01";
//precisamos escrever os dados post para o stream
using (var stream = requisicaoWeb.GetRequestStream())
{
stream.Write(MyJson, 0, dados.Length);
stream.Close();
}
//ler e exibir a resposta
using (var resposta = requisicaoWeb.GetResponse())
{
var streamDados = resposta.GetResponseStream();
StreamReader reader = new StreamReader(streamDados);
object objResponse = reader.ReadToEnd();
var post = objResponse.ToString();//JsonConvert.DeserializeObject<Post>(objResponse.ToString());
streamDados.Close();
resposta.Close();
}
Everything I try in C#, the JSON field on Fiddler is always empty and the "syntax View" description is always "Request Invalid".
Try it's;
public static string HttpPost(string URI, string Parameters)
{
System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
req.ContentType = "application/json; charset=utf-8";
req.Method = "POST";
req.Timeout = 600000;
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
req.ContentLength = bytes.Length;
System.IO.Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
System.Net.WebResponse resp = req.GetResponse();
if (resp == null)
return null;
System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}
I have just figure it out.
If anybody else has the same problem, here is the answer
string json = JsonConvert.SerializeObject(abc);
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("MyURL"); //==> I am filling it correctly
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var stringContent = new StringContent(JsonConvert.SerializeObject(abc), Encoding.UTF8, "application/json");
var response = client.PostAsync("MyURL", stringContent).Result; //==> I am filling my method correctly
Related
I'm consuming a Web API of an internal system in the company.
It's getting a payload in JSON format and returning a response with data in JSON format.
When sending the request with Postman, it returns the expected response (StatusCode=200 + a response text in JSON format). That means that everything is OK with the web service.
Now I have to develop an application in C# to send this HTTP request.
The problem is, that I receive as response content "OK" and not the expected JSON response gotten with Postman.
public HttpWebResponse SendRequest(string url, string checkOutFolder, string drawingNo, string login, string password)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/json";
request.Method = "GET";
request.Accept = "application/json";
string payload = GeneratePayLoad(checkOutFolder, drawingNo);
string header = CreateAuthorization(login, password);
request.Headers[HttpRequestHeader.Authorization] = header;
request.ServicePoint.Expect100Continue = false;
var type = request.GetType();
var currentMethod = type.GetProperty("CurrentMethod", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(request);
var methodType = currentMethod.GetType();
methodType.GetField("ContentBodyNotAllowed", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentMethod, false);
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(payload);
}
// Response
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string responseContent = rd.ReadToEnd();
Console.WriteLine(responseContent);
}
return response;
}
Has anyone already experiences something similar.
Can you help me?
EDIT
Following your suggestions
1) Changed the method to POST -> result is still the same
2) Used Postman's code generator and RestSharp -> result is still the same
public void Request(string url, string checkOutFolder, string drawingNo, string login, string password)
{
var client = new RestClient(url);
var request = new RestRequest();
request.Method = Method.Post;
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Basic **********");
var body = GeneratePayLoad(checkOutFolder, drawingNo);
request.AddParameter("application/json", body, ParameterType.RequestBody);
var response = client.Execute(request);
Console.WriteLine(response.Content);
}
Changed to HttpClient -> result still the same
using (var client = new HttpClient())
{
string uri = "******************";
string path = "destinationpath";
var endpoint = new Uri(uri);
string payload = GeneratePayLoad(path, "100-0000947591");
//FormUrlEncodedContent form = new FormUrlEncodedContent(payload);
var stringContent = new StringContent(payload);
var payload2 = new StringContent(payload, Encoding.UTF8, "application/json");
var byteArray = Encoding.ASCII.GetBytes("*******");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(client.DefaultRequestHeaders.Authorization.ToString()));
var result = client.PostAsync(endpoint, stringContent).Result.Content.ReadAsStringAsync().Result;
Console.WriteLine("test");
}
Wrote a Python code using requests Package -> delivers the same as Postman. So the problem is in the C# code.
Does anyone have an idea what is going on?
SOLVED
The issue was on the payload generation!
The request needs to be an HTTP POST and not HTTP GET because it contains JSON payload.
request.Method = "GET"; should be request.Method = "POST";
That would be one of the issue(s). I am not sure if there is something else that is wrong, but try changing the request method to POST and try again.
I try to convert HttpWebRequest to HttpClient but without success.
Can anybody help me?
It is my simple code with HttpWebRequest:
string url = "https://www.somesite.com/Service";
string postData = "text to send";
var data = Encoding.ASCII.GetBytes(postData);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "POST";
request.Proxy = null;
request.AllowAutoRedirect = false;
request.UserAgent = "Mozilla/5.0";
request.ContentType = "text/x-gwt-rpc; charset=UTF-8";
request.Headers.Add("Cookie", SetCookie);//get it after login
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseText = reader.ReadToEnd();
I think you can convert you HttpWebRequest based code to HttpClient based like this:
string url = "https://www.somesite.com/Service";
string postData = "text to send";
var data = Encoding.ASCII.GetBytes(postData);
var content = new ByteArrayContent(data);
using var httpHandler = new HttpClientHandler { UseCookies = false, AllowAutoRedirect = false };
using var client = new HttpClient(httpHandler);
client.DefaultRequestHeaders.Add("UserAgent","Mozilla/5.0");
client.DefaultRequestHeaders.Add("ContentType", "text/x-gwt-rpc; charset=UTF-8");
client.DefaultRequestHeaders.Add("Cookie", SetCookie);
using var requestMessage = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };
var response = await client.SendAsync(requestMessage);
var responseText = await response.Content.ReadAsStringAsync();
Remarks:
Instead of writing the Request's Stream manually you can use the ByteArrayContent abstraction for this. (Related SO topic)
In order to set the cookie(s) manually you have to turn-off the default behaviour. You can do this via the HttpClientHandler's UseCookies. (Related SO topic)
To set the headers manually you can use the HttpClient's DefaultRequestHeaders (Related SO topic)
The counterpart of GetResponse is the SendAsync
Instead of reading the Response's Stream manually you can use the HttpContent's ReadAsStringAsync (Related SO topic)
UPDATE: Include OP's amended code
var content = new StringContent(postData, Encoding.UTF8, "text/x-gwt-rpc");
So, instead of ByteArrayContent StringContent is being used.
Here is the code that I am using:
public static void FetchXML()
{
_url = new Uri("http://api.tumblr.com/v2/blog/" + _username + ".tumblr.com/likes?api_key=REc3Z6l4ZYss11a8lX6KKje0X8Hsi9U77SyaPbQrOBBCGJGA6D");
var client = new RestClient();
client.Authority = _url.ToString();
var request = new RestRequest();
request.AddParameter("limit", "20");
request.AddParameter("offset", _offset.ToString());
var response = client.Request(request);
var content = response.Content.ToString();
var parsedResponse = JsonParser.FromJson(content);
}
If I take the Uri value and paste it into my browser (using a valid Tumblr username) I'm getting the correct Json, but in my application the content of response is:
"{\"meta\":{\"status\":401,\"msg\":\"Unauthorized\"},\"response\":[]}"
Anyone have any idea why this is? According to the Tumblr API
retrieving likes should only need the API key, which I am providing.
Hi you can use the below code to get the response.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "GET";
request.ContentType = "Application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream receive = response.GetResponseStream();
StreamReader reader = new StreamReader(receive, Encoding.UTF8);
string respond = reader.ReadToEnd();
So I have an api that I want to call to. The first call is an ahoy call and in the body of the request I need to send the ship_type, piratename and my piratepass. I then want to read the response which has my treasure booty that i will use for later.
I'm able to do this with web request. but i feel like there is a better way to do it with webclient.
(way I currently do it in webrequest)
//Credentials for the Pirate api
string piratename = "IvanTheTerrible";
string piratepass= "YARRRRRRRR";
string URI = "https://www.PiratesSuperSecretHQ.com/sandyShores/api/respectmyauthority";
WebRequest wr = WebRequest.Create(URI);
wr.Method = "POST";
wr.ContentType = "application/x-www-form-urlencoded";
string bodyData = "ship_type=BattleCruiser&piratename=" + piratename + "&piratepass=" + piratepass;
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] byte1 = encoder.GetBytes(bodyData);
wr.ContentLength = byte1.Length;
//writes the body to the request
Stream newStream = wr.GetRequestStream();
newStream.Write(byte1, 0, byte1.Length);
newStream.Close();
WebResponse wrep = wr.GetResponse();
string result;
using (var reader = new StreamReader(wrep.GetResponseStream()))
{
result = reader.ReadToEnd(); // do something fun...
}
Thanks in advance either way.
You can do with this simple code
Uri uri = new Uri("yourUri");
string data = "yourData";
WebClient client = new WebClient();
var result = client.UploadString(uri, data);
Remember that you can use UploadStringTaskAsync if you want to be async
You can try like below as well:
public String wcPost(){
Map<String, String> bodyMap = new HashMap();
bodyMap.put("key1","value1");
WebClient client = WebClient.builder()
.baseUrl("domainURL")
.build();
String responseSpec = client.post()
.uri("URI")
.headers(h -> h.setBearerAuth("token if any"))
.body(BodyInserters.fromValue(bodyMap))
.exchange()
.flatMap(clientResponse -> {
if (clientResponse.statusCode().is5xxServerError()) {
clientResponse.body((clientHttpResponse, context) -> {
return clientHttpResponse.getBody();
});
return clientResponse.bodyToMono(String.class);
}
else
return clientResponse.bodyToMono(String.class);
})
.block();
return responseSpec;
}
Here's my code for Request and Response.
System.IO.MemoryStream xmlStream = null;
HttpWebRequest HttpReq = (HttpWebRequest)WebRequest.Create(url);
xmlStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(format));
byte[] buf2 = xmlStream.ToArray();
System.Text.UTF8Encoding UTF8Enc = new System.Text.UTF8Encoding();
string s = UTF8Enc.GetString(buf2);
string sPost = "XMLData=" + System.Web.HttpUtility.UrlDecode(s);
byte[] bPostData = UTF8Enc.GetBytes(sPost);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/x-www-form-urlencoded";
HttpReq.Timeout = 30000;
request.Method = "POST";
request.KeepAlive = true;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bPostData, 0, bPostData.Length);
requestStream.Close();
}
string responseString = "";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
responseString = sr.ReadToEnd();
}
No part of this code crashes. The "format" string is the one with XML in it. By the end when you try to see what's in the responseString, it's an empty string. I am supposed to see the XML sent back to me from the URL. Is there something missing in this code?
I would recommend a simplification of this messy code:
using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "XMLData", format }
};
byte[] resultBuffer = client.UploadValues(url, values);
string result = Encoding.UTF8.GetString(resultBuffer);
}
and if you wanted to upload the XML directly in the POST body you shouldn't be using application/x-www-form-urlencoded as content type. You probably should specify the correct content type, like this:
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "text/xml";
var data = Encoding.UTF8.GetBytes(format);
byte[] resultBuffer = client.UploadData(url, data);
string result = Encoding.UTF8.GetString(resultBuffer);
}