C# HttpWebRequest "Request Header" in JSON POST - c#

I am translating a JSON API into C# Methods, and I encountered a Problem where the JSON RPC API (POST) says
All other methods require the result from authentication ( = sessionId), either per pathparameter
;jsessionid=644AFBF2C1B592B68C6B04938BD26965
or per cookie (RequestHeader)
JSESSIONID=644AFBF2C1B592B68C6B04938BD26965
My current WebRequest Method:
private async static Task<string> SendJsonAndWait(string json, string url, string sessionId) {
string result;
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using(StreamWriter streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync())) {
await streamWriter.WriteAsync(json);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse httpResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
Stream responseStream = httpResponse.GetResponseStream();
if(responseStream == null)
throw new Exception("Response Stream was null!");
using(StreamReader streamReader = new StreamReader(responseStream)) {
result = await streamReader.ReadToEndAsync();
}
return result;
}
How do I add the JSESSIONID Parameter to my WebRequest? I am not very familiar with WebRequests, please explain briefly!
Thank you!

Use Cookies.
Your Case would look like this;
private async static Task<string> SendJsonAndWait(string json, string url, string sessionId) {
Uri uri = new Uri(url);
string result;
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
//Add the JSESSIONID Cookie
if(httpWebRequest.CookieContainer == null)
httpWebRequest.CookieContainer = new CookieContainer();
if(!string.IsNullOrWhiteSpace(sessionId))
httpWebRequest.CookieContainer.Add(new Cookie("JSESSIONID", sessionId, "/", uri.Host));
using(StreamWriter streamWriter = new StreamWriter(await httpWebRequest.GetRequestStreamAsync())) {
await streamWriter.WriteAsync(json);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse httpResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync();
Stream responseStream = httpResponse.GetResponseStream();
if(responseStream == null)
throw new Exception("Response Stream was null!");
using(StreamReader streamReader = new StreamReader(responseStream)) {
result = await streamReader.ReadToEndAsync();
}
return result;
}

You can add the token directly to your URL :
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create($"{url}?jsessionid={sessionId}");
Or in the headers :
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create({url);
httpWebRequest.Headers["JSESSIONID"] = sessionId;

Related

Getting null in httpResponseMessage when calling REST API using HTTPClient

I am trying to execute a REST API which uses HTTP POST. The API consumes and produces xml content. I am getting null in httpResponseMessage and no exception is thrown. I tried executing the same REST API through HttpWebRequest I am getting the response Below you can find Working and Not Working case. Performance wise HttpWebRequest or HTTPClient which is better ?
Not Working case HTTPClient
try {
using(var client = new HttpClient()) {
Console.WriteLine(inputxml);
var httpContent = new StringContent(inputxml, Encoding.UTF8, "application/xml");
Uri testUri = new Uri("http://127.0.0.1:8080/rest/services/getDocument");
var httpResponseMessage = await client.PostAsync(testUri, httpContent);
Console.WriteLine(httpResponseMessage.Content.ReadAsStringAsync());
if (httpResponseMessage.StatusCode == HttpStatusCode.OK) {
var messageContents = await httpResponseMessage.Content.ReadAsStringAsync();
}
}
}
Working Case HTTPWebREquest
HttpWebRequest request = (HttpWebRequest) WebRequest.Create("http://127.0.0.1:8080/rest/services/getDocument");
byte[] bytes = Encoding.UTF8.GetBytes(inputxml.ToString());
request.ContentType = "application/xml";
request.ContentLength = bytes.Length;
request.Method = "POST";
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
HttpWebResponse response;
response = (HttpWebResponse) request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK) {
Stream responseStream = response.GetResponseStream();
string responseStr = new StreamReader(responseStream).ReadToEnd();
Console.WriteLine("responseStr " + responseStr);
return responseStr;
}
return null;
}
Here:
Console.WriteLine(httpResponseMessage.Content.ReadAsStringAsync());
You're reading the response body, and printing System.Threading.Task1` to the console. Then the next time you try to read the response body again, its stream is at its end and won't return anything.
Read the content once, await the call and store the result in a variable.
You can use RestSharp for sending HTTP Requests.
For me, the best and the simplest method for HTTP Communication.
public string SendRequest(String xml)
{
string responseMessage= "";
RestClient restClient;
restClient = new RestClient("http://127.0.0.1:8080/rest/services/getDocument");
RestRequest restRequest = new RestRequest(Method.POST);
restRequest.AddHeader("Accept", "application/xml");
restRequest.AddHeader("Content-Type", "application/xml");
restRequest.AddXmlBody(xml);
IRestResponse restResponse = restClient.Execute(restRequest);
if (restResponse.StatusCode == HttpStatusCode.OK)
{
responseMessage= restResponse.Content;
}
return responseMessage;
}
}

Convert CURL "-i --user" to C# HttpWebRequest

I want to run a CURL POST to send SMS message via Plivo API service.
I do it by using HttpWebRequest in C# (see below).
Parametres as as follow:
POSTurl = "https://api.plivo.com/v1/Account/MA****************M2/Message/'”
JSONRequest == "src=+972545675453&dst=0545675453&text=TEST”
In their docs I need to user the following parameter:
-i --user AUTH_ID:AUTH_TOKEN
I don't know how to implement this but it not work (401 error -unauthorised)
I tried to use it instead auth parameter in my code as follow:
auth == “MA****************MM2:Yj**************************M5ZjA4"
Need some advice 😳
Thanks
This is my code:
public static SqlString POSTSG(String POSTurl, String auth, SqlString JSONRequest)
{
SqlPipe pipe = SqlContext.Pipe;
//Create Request
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(POSTurl);
myHttpWebRequest.Method = "POST";
myHttpWebRequest.Headers.Add("Authorization", auth);
myHttpWebRequest.ContentType = "application/json; charset=utf-8";
StreamWriter streamWriter = new StreamWriter(myHttpWebRequest.GetRequestStream(), System.Text.Encoding.UTF8);
streamWriter.Write(JSONRequest);
streamWriter.Flush();
streamWriter.Close();
// Get the response
HttpWebResponse httpResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
// Create a new read stream for the response body and read it
StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream());
SqlString result = streamReader.ReadToEnd();
return (result);
}
Needed to send User:Pass as network credentials instead of auth. and use 'application/json' as content type.
[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
public static SqlString POST(String POSTurl, String auth,String user, String pass, String ContentType, SqlString JSONRequest)
{
SqlPipe pipe = SqlContext.Pipe;
//Create Request
HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(POSTurl);
myHttpWebRequest.Method = "POST";
if (user != null) { myHttpWebRequest.Credentials = new NetworkCredential(user, pass); }
else if (auth!=null) { myHttpWebRequest.Headers.Add("Authorization", auth); }
myHttpWebRequest.ContentType = ContentType;
StreamWriter streamWriter = new StreamWriter(myHttpWebRequest.GetRequestStream());
streamWriter.Write(JSONRequest);
streamWriter.Flush();
streamWriter.Close();
// Get the response
HttpWebResponse httpResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
// Create a new read stream for the response body and read it
StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream(), System.Text.Encoding.UTF8);
SqlString result = streamReader.ReadToEnd();
return (result);
}

HttpWebRequest return error 500 when GetResponse()

I'm trying to get a response from SOAP webservice, but I'm falling into a webexception Error 500.
This my class to get a response:
public static string getResponse()
{
StringBuilder xml = new StringBuilder();
//xml.Append(#"<?xml version=""1.0"" encoding=""utf-8""?>");
xml.Append(#"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:br=""http://www.totvs.com.br/br/"" >").Replace(#"\", "");
xml.Append("<soap:Envelope/>");
xml.Append("<soapenv:Body>");
xml.Append("<br:RealizarConsultaSQLAuth>");
xml.Append("<br:codSentenca>GLOBAL_054</br:codSentenca>");
xml.Append("<br:codColigada>0</br:codColigada>");
xml.Append("<br:codAplicacao>V</br:codAplicacao>");
xml.Append("<br:Usuario>xxxx</br:Usuario>");
xml.Append("<br:Senha>xxxx</br:Senha>");
xml.Append("<br:parameters>codcoligada=1;codsistema=V;codusuario=mestre</br:parameters>");
xml.Append("</br:RealizarConsultaSQLAuth>");
xml.Append("</soapenv:Body>");
xml.Append("</soapenv:Envelope>");
string s = getUKMailData(xml.ToString(), "http://xxx.xxxx.com.br:99/xxxx/wsConsultaSQL.asmx");
return s;
}
public static string getUKMailData(string xml, string address)
{
string result = "";
HttpWebRequest request = CreateWebRequest(address);
XmlDocument soapEnvelopeXml = new XmlDocument();
string teste = xml.Replace(#"\", "");
soapEnvelopeXml.LoadXml(teste);
try
{
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
result = soapResult;
}
}
}
catch (WebException wex)
{
var pageContent = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
}
return result;
}
public static HttpWebRequest CreateWebRequest(string url)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAP:Action");
webRequest.Headers.Add("username", "xxx");
webRequest.Headers.Add("password", "xxx");
// webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
webRequest.PreAuthenticate = true;
webRequest.Credentials = CredentialCache.DefaultCredentials;
return webRequest;
}
anyone can help me? I already read a series of articles that unfortunately did not help me. Thanks a lot!
Your request maybe true but server-side doesn't know how to process your data. Maybe parameters which are sent fault. Please check your server-side so end-point.

C# JSON Post using HttpWebRequest

I am new to JSON and C# and trying to write a code that will perform an http web request POST to get a token. Below is my code but I keep getting 400 bad request. Probably my codes just incorrect and I will appreciate for any helps on this. Below is my codes :
static public string GetAuthorizationToken()
{
string token = string.Empty;
string requestUrl = "some URL";
HttpWebRequest httpWebRequest = WebRequest.Create(requestUrl) as HttpWebRequest;
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "x-www-form-urlencoded";
Dictionary<string, string> postParameters = new Dictionary<string, string>();
postParameters.Add("grant", "some credentials");
postParameters.Add("id", "1234123411");
postParameters.Add("secret", "1234123411");
postParameters.Add("scope", "abcd");
string postData = "";
foreach (string key in postParameters.Keys)
{
postData += WebUtility.UrlEncode(key) + "="
+ WebUtility.UrlEncode(postParameters[key]) + "&";
}
byte[] data = Encoding.ASCII.GetBytes(postData);
httpWebRequest.ContentLength = data.Length;
Stream requestStream = httpWebRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
requestStream.Close();
TokenResponse tokenResponse = new TokenResponse();
using (HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
DataContractJsonSerializer responseSerializer = new DataContractJsonSerializer(typeof(TokenResponse));
Stream responseStream = response.GetResponseStream();
object objResponse = responseSerializer.ReadObject(responseStream);
tokenResponse = objResponse as TokenResponse;
response.Close();
if (tokenResponse != null)
{
return tokenResponse.accessToken;
}
}
return token;
}
Here is a precise and accurate example of a POST request and reading the response(though without serializing the JSON data). Only mistake I see so far in your code is an incorrect ContentType also we can't see what url you are trying to send the server(but odds are that it is incorrect). Hope it helps you advance.
using System;
using System.Collections.Generic;
using System.Net;
using System.IO;
namespace SExperiment
{
class MainClass
{
public static void Main(string[] args)
{
try{
string webAddr="http://gurujsonrpc.appspot.com/guru";
var httpWebRequest = WebRequest.CreateHttp(webAddr);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = "{ \"method\" : \"guru.test\", \"params\" : [ \"Guru\" ], \"id\" : 123 }";
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
Console.WriteLine(responseText);
//Now you have your response.
//or false depending on information in the response
}
}catch(WebException ex){
Console.WriteLine(ex.Message);
}
}
}
}
You have set requestUrl to "some URL". Please try with a web address that exists, in addition to changing the content type to "application/json".

How to make ordinary WebRequest async and awaitable?

I need to make the following code async and awaitable.
I need to get a lot of data from the web server, and then this data will be used to populate the xaml page in my application.
So, I need the DefLogin() method to be awaitable.
Is it possible?
public void DefLogin()
{
postData = "My Data To Post";
var url = new Uri("Url To Post to", UriKind.Absolute);
webRequest = WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "text/xml";
webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), webRequest);
}
public void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
Stream postStream = webRequest.EndGetRequestStream(asynchronousResult);
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
Debug.WriteLine("Start BEGINGetResponse");
webRequest.BeginGetResponse(new AsyncCallback(GetResponseCallback), webRequest);
}
public void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response;
response = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamReader = new StreamReader(streamResponse);
string Response = streamReader.ReadToEnd();
streamResponse.Close();
streamReader.Close();
response.Close();
if (Response == "")
{
//show some error msg to the user
Debug.WriteLine("ERROR");
}
else
{
//Your response will be available in "Response"
Debug.WriteLine(Response);
}
}
catch (WebException)
{
//error
}
}
I saw this question on StackOverflow: Converting ordinary Http Post web request with Async and Await, but I could not understand the answer properly.
Please can anyone help? I would be really grateful!
You can use TaskFactory.FromAsync to convert APM to TAP, making a lot of tiny extension methods like this:
public static Task<Stream> GetRequestStreamAsync(this WebRequest request)
{
return TaskFactory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null);
}
and do the same for WebRequest.GetResponse and (if necessary) Stream.Write, Stream.Flush, etc.
Then you can write your actual logic using async and await without any callbacks:
public async Task DefLoginAsync()
{
postData = "My Data To Post";
var url = new Uri("Url To Post to", UriKind.Absolute);
webRequest = WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ContentType = "text/xml";
using (Stream postStream = await webRequest.GetRequestStreamAsync())
{
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
await postStream.WriteAsync(byteArray, 0, byteArray.Length);
await postStream.FlushAsync();
}
try
{
string Response;
using (var response = (HttpWebResponse)await webRequest.GetResponseAsync());
using (Stream streamResponse = response.GetResponseStream())
using (StreamReader streamReader = new StreamReader(streamResponse))
{
Response = await streamReader.ReadToEndAsync();
}
if (Response == "")
{
//show some error msg to the user
Debug.WriteLine("ERROR");
}
else
{
//Your response will be available in "Response"
Debug.WriteLine(Response);
}
}
catch (WebException)
{
//error
}
}

Categories