I have a PHP web service using JSON that I need to post requests to from a Silverlight application. I had used the HttpWebRequest class before, in a regular C# application and it worked flawlessly. In my Silverlight application, however, the callbacks for the BeginGetRequestStream and BeginGetResponse methods are not getting called.
I tried testing it out in about every way without success. Note that the data I am sending is not long - just a 32 character string most of the time. I checked if the callbacks were getting called at all, and they weren't being called. Here is my code:
public void Request(Command cmd, Dictionary<string, string> data)
{
Dictionary<string, object> fullRequest = new Dictionary<string,object>();
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
StringWriter writer = new StringWriter(new StringBuilder());
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(writer, fullRequest);
string query = "query=" + writer.ToString();
request.ContentLength = query.Length;
request.ContentType = "text/json";
_queue.Enqueue(new KeyValuePair<Command, string>(cmd, query));
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
public void GetRequestStreamCallback(IAsyncResult target)
{
HttpWebRequest request = (HttpWebRequest)target.AsyncState;
Stream postStream = request.EndGetRequestStream(target);
string postData = "";
//not sure why I have to do this. in the Silverlight documentation
//Queue<> is supposed to have the SyncRoot property
//but I get an error if I just try _queue.SyncRoot
lock ((_queue as ICollection).SyncRoot)
{
postData = _queue.Dequeue().Value;
}
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
public void GetResponseCallback(IAsyncResult result)
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
streamResponse.Close();
streamRead.Close();
response.Close();
JsonSerializer serializer = new JsonSerializer();
Dictionary<string, object> responseData = new Dictionary<string, object>();
responseData = (Dictionary<string, object>)serializer.Deserialize(new StringReader(responseString), typeof(Dictionary<string, object>));
if (_data.ContainsKey(responseData["key"] as string))
{
_data[responseData["key"] as string] = responseData;
}
else
{
_data.Add(responseData["key"] as string, responseData);
}
I also tried this:
IAsyncResult resultRequest = request.BeginGetRequestStream(null, null) as IAsyncResult;
Stream postStream = request.EndGetRequestStream(resultRequest );
To get the stream synchronously (yes, bad style, I just wanted to see if it will work). No success .
Thanks in advance.
Related
I am using below code to make an API call from my C# code with WebRequest:
public object GetData()
{
object response = "";
string token = "EF232354";
string baseUrl = ConfigurationManager.AppSettings["BaseURL"].ToString();
string endPoint = ConfigurationManager.AppSettings["EndPoint"].ToString();
var httpWebRequest = (HttpWebRequest) WebRequest.Create(baseUrl + endPoint);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = HttpVerb.GET.ToString();
httpWebRequest.Headers.Add("token", token);
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
Stream dataStream = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
using(JsonReader sdr = new JsonTextReader(reader))
{
JsonSerializer serializer = new JsonSerializer();
response = serializer.Deserialize(sdr);
}
return response;
}
Sometimes I am getting:
Message: The remote server returned an error: (504) Gateway Timeout.
Exception Type: System.Net.WebException
And how many requests can WebRequest make at a time?
I was adapting the question to demonstrate reading to a memory stream, when I noticed that the response was not being disposed. This is 95% likely to be your underlying problem. Streams and StreamReaders are also disposable and should be wrapped with using() closures.
public object GetData()
{
object response = "";
string token = "EF232354";
string baseUrl = ConfigurationManager.AppSettings["BaseURL"].ToString();
string endPoint = ConfigurationManager.AppSettings["EndPoint"].ToString();
var httpWebRequest = (HttpWebRequest) WebRequest.Create(baseUrl + endPoint);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = HttpVerb.GET.ToString();
httpWebRequest.Headers.Add("token", token);
using (var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse())
{
using (Stream dataStream = httpResponse.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataStream))
{
using(JsonReader sdr = new JsonTextReader(reader))
{
JsonSerializer serializer = new JsonSerializer();
response = serializer.Deserialize(sdr);
}
return response;
}
}
httpResponse.Close(); // For good measure. *should* be covered by Dispose.
}
}
I have this java code and I want to make C# code that does the same thing.
Stripe.apiKey = "sk_test_2uoGykz3oyw8GNHWiBVEQY7N";
Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", 400);
chargeParams.put("currency", "usd");
chargeParams.put("source", "tok_160DSpIZJBCsfX4YCKJKjg2O"); // obtained with Stripe.js
chargeParams.put("description", "Charge for test#example.com");
Charge.create(chargeParams);
Stripe Payment using (C#) WCF Rest Service. This Code is correct to make payment to stripe gateway. You don't need any stripe dll. This will help to make payment.
PrivateKey = WebConfigurationManager.AppSettings["StripeApiKey"].ToString();
StringBuilder postUrl = new StringBuilder();
postUrl.Append("&card=");
postUrl.Append(paymentDetail.Token);
postUrl.Append("¤cy=USD");
postUrl.Append("&amount=");
postUrl.Append(paymentDetail.Amount);
byte[] formbytes = System.Text.ASCIIEncoding.Default.GetBytes(postUrl.ToString());
//Create a new HTTP request object, set the method to POST and write the POST data to it
var webrequest = (HttpWebRequest)WebRequest.Create("https://api.stripe.com/v1/charges");
webrequest.Method = "POST";
webrequest.UserAgent = "Stripe Payment";
webrequest.ContentType = "application/x-www-form-urlencoded";
webrequest.Headers.Add("Stripe-Version", "2015-04-07");
webrequest.Headers.Add("Authorization", String.Concat("Basic ", (Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:", this.PrivateKey))))));
using (Stream postStream = webrequest.GetRequestStream())
{
postStream.Write(formbytes, 0, formbytes.Length);
}
//Make the request, get a response and pull the data out of the response stream
StreamReader reader = null;
string stripeResponse;
try
{
var webresponse = (HttpWebResponse)webrequest.GetResponse();
Stream responseStream = webresponse.GetResponseStream();
reader = new StreamReader(responseStream);
stripeResponse = reader.ReadToEnd();
}
catch (WebException exception)
{
using (WebResponse response = exception.Response)
{
using (Stream data = response.GetResponseStream())
using (reader = new StreamReader(data))
{
stripeResponse = reader.ReadToEnd();
}
}
}
C# and Java have similar syntaxes, in fact the only change you would need to make to the code you posted is change the HashMap<String, Object> in to a Dictionary<String, Object>
Stripe.apiKey = "sk_test_2uoGykz3oyw8GNHWiBVEQY7N";
Dictionary<String, Object> chargeParams = new Dictionary<String, Object>();
chargeParams.Add("amount", 400);
chargeParams.Add("currency", "usd");
chargeParams.Add("source", "tok_160DSpIZJBCsfX4YCKJKjg2O"); // obtained with Stripe.js
chargeParams.Add("description", "Charge for test#example.com");
Charge.Create(chargeParams);
I'm trying to post data to a web server with such code:
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
//request.CookieContainer = new CookieContainer();
//request.CookieContainer.Add(new Uri(uri), new Cookie());
string postData = parameters.ToQueryString();
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
try
{
using (Stream dataStream = await request.GetRequestStreamAsync())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
WebResponse response = await request.GetResponseAsync();
using (Stream dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
return await reader.ReadToEndAsync();
}
}
catch (Exception e)
{
return e.Message + e.StackTrace;
}
Those bits of information that I found on the Internet suggest that it's because response headers are incorrect, but it's not for sure.
Could you please tell how to do http post request with parameters and if suggestion described above is correct, how to tell system.net not to check response headers?
This is how I'm calling this method:
Dictionary<string, string> par = new Dictionary<string, string>();
par.Add("station_id_from", "2218000");
par.Add("station_id_till", "2200001");
par.Add("train", "112Л");
par.Add("coach_num", "4");
par.Add("coach_class", "Б");
par.Add("coach_type_id", "3");
par.Add("date_dep", "1424531880");
par.Add("change_scheme", "0");
debugOutput.Text = await Requests.makeRequestAsync("http://booking.uz.gov.ua/purchase/coach", par);
As I have gone through the examples,I have come across only asynchronous http web request having callback methods,like:-
private void getList(string restApiPath, Dictionary<string, string> output, Type type, string label)
{
webRequest = (HttpWebRequest)WebRequest.Create(restApiPath);
path = restApiPath;
labelValue = label;
webRequest.Method = "POST";
webRequest.ContentType = Globals.POST_CONTENT_TYPE;
webRequest.Headers["st"] = MPFPConstants.serviceType;
webRequest.BeginGetRequestStream(result =>
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
// End the stream request operation
Stream postStream = request.EndGetRequestStream(result);
// Create the post data
string reqData = Utils.getStringFromList(output);
string encode = RESTApi.encodeForTokenRequest(reqData);
byte[] byteArray = Encoding.UTF8.GetBytes(encode);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
request.BeginGetResponse(new AsyncCallback(GetResponseCallbackForSpecificConditions), request);
}, webRequest);
}
private void GetResponseCallbackForSpecificConditions(IAsyncResult ar)
{
//code
}
Kindly Suggest me if we can make a synchronous httpwebrequest for wp8?
Why not try this, it works in a Desktop app:
using (Stream TextRequestStream = UsedWebRequest.GetRequestStream())
{
TextRequestStream.Write(ByteArray, 0, ByteArray.Length);
TextRequestStream.Flush();
}
HttpWebResponse TokenWebResponse = (HttpWebResponse)UsedWebRequest.GetResponse();
Stream ResponseStream = TokenWebResponse.GetResponseStream();
StreamReader ResponseStreamReader = new StreamReader(ResponseStream);
string Response = ResponseStreamReader.ReadToEnd();
ResponseStreamReader.Close();
ResponseStream.Close();
Why not try restsharp?
sample POST code looks like,
RestClient _authClient = new RestClient("https://sample.com/account/login");
RestRequest _credentials = new RestRequest(Method.POST);
_credentials.AddCookie(_cookie[0].Name, _cookie[0].Value);
_credentials.AddParameter("userLogin", _username, ParameterType.GetOrPost);
_credentials.AddParameter("userPassword", _password, ParameterType.GetOrPost);
_credentials.AddParameter("submit", "", ParameterType.GetOrPost);
RestResponse _credentialResponse = (RestResponse)_authClient.Execute(_credentials);
Console.WriteLine("Authentication phase Uri : " + _credentialResponse.ResponseUri);
I have the following method in a C# project which builds a web request to consume a web service:
private HttpWebRequest BuildRequest(string fullUri, object param, RequestMethod method, Dictionary<string, string> requestHeaders)
{
HttpWebRequest request = WebRequest.Create(fullUri) as HttpWebRequest;
request.Method = method.ToString().ToUpper();
request.Accept = "application/json";
request.ContentType = "application/json";
foreach (var h in requestHeaders)
{
request.Headers.Add(string.Format("{0}: {1}", h.Key, h.Value));
}
if (method == RequestMethod.Post)
{
JavaScriptSerializer ser = new JavaScriptSerializer();
string postData = ser.Serialize(param);
request.ContentLength = postData.Length;
Stream s = request.GetRequestStream();
StreamWriter sw = new StreamWriter(s);
sw.Write(postData);
sw.Flush();
}
return request;
}
Now I am wanting to do the same thing in Java but cant quite figure out how. So far I have...
private HttpRequestBase BuildRequest(String fullUri, Object param,
RequestMethod method, HashMap<String, String> requestHeaders) {
HttpRequestBase request = null;
if(method == RequestMethod.GET) {
request = new HttpGet(fullUri);
} else if (method == RequestMethod.POST) {
request = new HttpPost(fullUri);
}
request.addHeader(new BasicHeader("Accept", "application/json"));
request.addHeader(new BasicHeader("ContentType", "application/json"));
for(Map.Entry<String, String> header : requestHeaders.entrySet()) {
request.addHeader(new BasicHeader(header.getKey(), header.getValue()));
}
return request;
}
As far as I can tell that looks like it will work but I need to get the request stream like I do in the C# version in order to send an object as json but cant see how to get it. So my question is how to get it from a HttpRequestBase or any other object that I can use to build a HttpRequest in java.
Thanks.
FYI.. RequestMethod is an Enum either GET or POST"
And this is in an android application so I am able to use anything in the android sdk.