Setup time Metrics for Webservice Call - c#

I am calling a webservice to send json data by post method. Here is the code for that:
string sample_url = "mywebservice/createsample;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(sample_url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = new CookieContainer();
CookieCollection cookcol = new CookieCollection();
cookcol.Add(cookie);
string body= json data
byte[] postBytes = Encoding.UTF8.GetBytes(body);
request.ContentLength = postBytes.Length;
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Close();
WebResponse response = request.GetResponse();
string satus = ((HttpWebResponse)response).StatusDescription;
postStream = response.GetResponseStream();
StreamReader reader = new StreamReader(postStream);
I need to get some timestamp around this webservice request and response as the service seems quite slow. How do I put the countdown timer around this? Thanks for your response.

You can use the Stopwatch class:
Stopwatch sw = new Stopwatch();
sw.Start();
// your code to measure here
sw.Stop();
// print sw.Elapsed

Beware that you aren't testing your own network latency as well. If you are interested specifically in how long each service call takes, you should probably use a Stopwatch as per #nvoigt answer, but put this round your service implementation method.

Related

Long running, but finite length HttpWebRequest Callout gets only partial data

I am trying to work with a 3rd party service api . One of the methods they have brings in all records which takes a lot of time , about 9 mins ( i tried this using chrome app "Advanced Rest Client").
I have tried setting the webRequest.Timeout = 3600000;// Timeout.Infinite;
But it always comes back after maybe 2 minutes and the result contains 135 records (whereas the chrome app gets back 1050 records, which is correct #)
I am using the same parameters in both cases (i send it as POST data); so why is there difference in the results ?
I am using this code in a class library which will be used in a WPF application.
Is there a max value for timeout ?
Timeout.Infinite is setting it to '-1' , is this right ?
What are the other workarounds to get all data ?
Any help/suggestion is greatly appreciated.
Update: Adding code
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(url);
AllDevicesList devInfo = null;
try
{
string postData = "";
foreach (string key in postParameters.Keys)
{
postData += HttpUtility.UrlEncode(key) + "="
+ HttpUtility.UrlEncode(postParameters[key]) + "&";
}
postData = postData.TrimEnd('&');
if (cookie == null)
webRequest.CookieContainer = new CookieContainer();
else
webRequest.CookieContainer = cookie;
webRequest.Timeout = 3600000;// Timeout.Infinite; // 1000000;
webRequest.KeepAlive = true;
webRequest.Method = "POST";
byte[] data = Encoding.ASCII.GetBytes(postData);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.ContentLength = data.Length;
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(data, 0, data.Length);
WebResponse WebResp = webRequest.GetResponse();
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(AllDevicesList));
object objResponse = jsonSerializer.ReadObject(WebResp.GetResponseStream());
devInfo = objResponse as AllDevicesList;
requestStream.Close();
WebResp.Close();
I have changed the implementation to Asynchronous and now i get all the records.
Thanks for all your responses.

How to upload a text/XML file to a web service

I have a web service URL which has username and password authentication mode. I have to first pass the username and password, and if I am authenticated, I can upload a text or XML file onto the server. I am looking for a C# code to do the same process, but I'm unable to find it.
Any suggestions would be highly appreciated.
I am using following code-
if (!string.IsNullOrEmpty(txtfile))
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.KeepAlive = false;
request.SendChunked = true;
request.AllowAutoRedirect = true;
request.Method = "Post";
request.ContentType = "text/xml";
request.Credentials = new NetworkCredential(userName, password);
var encoder = new UTF8Encoding();
var data = encoder.GetBytes(txtfile);
request.ContentLength = data.Length;
var reqStream = request.GetRequestStream();
reqStream.Write(data, 0, data.Length);
reqStream.Close();
WebResponse response = null;
response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
}
You might want to try using the WebClient Class. There is a simple example about the WebClient.UploadFile Method which could fit your scenario.

Adding a body to a HttpWebRequest that is being used with the azure service mgmt api

How would i go about adding to the body of a HttpWebRequest?
The body needs to be made up of the following
<?xml version="1.0" encoding="utf-8"?>
<ChangeConfiguration xmlns="http://schemas.microsoft.com/windowsazure">
<Configuration>base-64-encoded-configuration-file</Configuration>
<TreatWarningsAsError>true|false</TreatWarningsAsError>
<Mode>Auto|Manual</Mode>
</ChangeConfiguration>
Any help is much appreciated
byte[] buf = Encoding.UTF8.GetBytes(xml);
request.Method = "POST";
request.ContentType = "text/xml";
request.ContentLength = buf.Length;
request.GetRequestStream().Write(buf, 0, buf.Length);
var HttpWebResponse = (HttpWebResponse)request.GetResponse();
Don't know about Azure, but here just the general outline to send data with a HttpWebRequest :
string xml = "<someXml></someXml>";
var payload = UTF8Encoding.UTF8.GetBytes(xml);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://foo.com");
request.Method = "POST";
request.ContentLength = payload.Length;
using(var stream = request.GetRequestStream())
stream.Write(payload, 0, payload.Length);
If you don't need a HttpWebRequest for some reason, using a WebClient for uploading data is much more concise:
using (WebClient wc = new WebClient())
{
var result = wc.UploadData("http://foo.com", payload);
}
My book chapter showing how to use the Windows Azure Service Management API (and create the payload) can be downloaded for free.

Programmatically login to google app engine c#

I've tried to login to my google app engine application from ASP.NET for a few days, but no luck. I've read the following articles and got the basic ideas. But nothing works for me.
http://code.activestate.com/recipes/577217-routines-for-programmatically-authenticating-with-/
http://dalelane.co.uk/blog/?p=303
http://dalelane.co.uk/blog/?p=894
http://krasserm.blogspot.com/2010/01/accessing-security-enabled-google-app.html
http://blog.notdot.net/2010/05/Authenticating-against-App-Engine-from-an-Android-app
I know what to do. 1) Get an auth token from ClientLogin. 2) Get a cookie from Google App Engine. 3) Post data to my app with the cookie (Yes, I want to post data, not redirect after the second part). But the third part doesn't work for me at all. It give me 403 error. Here is my code:
void PostToGAE()
{
var auth = GetAuth(); // I can get the authtoken
var cookies = GetCookies(auth); // I can get the ACSID cookie
var url = string.Format("http://test.appspot.com/do/something/");
var content = "testvalue=test";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.KeepAlive = false;
request.CookieContainer = cookies;
byte[] byteArray = Encoding.UTF8.GetBytes(content);
request.ContentLength = byteArray.Length;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); // This gives me 403
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string result = reader.ReadToEnd();
reader.Close();
}
CookieContainer GetCookies(string auth)
{
CookieContainer cookies = new CookieContainer();
var url = string.Format("http://test.appspot.com/_ah/login?auth={0}",
System.Web.HttpUtility.UrlEncode(auth));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.AllowAutoRedirect = false;
request.CookieContainer = cookies;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string result = reader.ReadToEnd();
reader.Close();
return cookies;
}
string GetAuth()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.google.com/accounts/ClientLogin");
var content = "Email=test#gmail.com&Passwd=testpass&service=ah&accountType=HOSTED_OR_GOOGLE";
byte[] byteArray = Encoding.UTF8.GetBytes(content);
request.ContentLength = byteArray.Length;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string loginStuff = reader.ReadToEnd();
reader.Close();
var auth = loginStuff.Substring(loginStuff.IndexOf("Auth")).Replace("Auth=", "").TrimEnd('\n');
return auth;
}
My app.yaml looks like this:
- url: /do/something/
script: something.py
login: admin
If I change the method POST to GET, that works. Could anyone tell me how I can post data?
Thanks.
EDITED:
Still no luck. I've tried several ways such as changing to [login: required] in app.yaml, adding [secure: always] to app.yaml and changing the request protocol to https, appending continue parameter to /_ah/login, but all of them don't work :(
I totally have no idea why POST doesn't work at all but GET. Any ideas?
I made it. I was on the wrong track. That was not the problem of app engine but Django. I am using Django-nonrel on google app engine, and I totally forgot to put #csrf_exempt decorator to my handler. I had the same problem before, but again. Anyway, the code above has been apparently working correctly since at the beginning. What a smart boy :)

C#: How to POST large string via WebRequest?

how can i upload a large string (in my case XML with BLOB) with POST without getting Timeout with GetResponse?
Changing the timeout helps, but this isn't really a solution.
If the Server is really death or the POST was interrupted i have to wait for the extrem large timeout.
Any Idea?
HttpWebRequest webRequest = null;
string response = "";
byte[] bytes = Encoding.UTF8.GetBytes(xml);
try
{
webRequest = (HttpWebRequest)WebRequest.Create("http://" + this.host + ":" + this.port);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
webRequest.Timeout = 5000;
webRequest.ContentLength = bytes.Length;
using (Stream requeststream = webRequest.GetRequestStream())
{
requeststream.Write(bytes, 0, bytes.Length);
requeststream.Close();
}
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
{
using (StreamReader sr = new StreamReader(webResponse.GetResponseStream()))
{
response = sr.ReadToEnd().Trim();
sr.Close();
}
webResponse.Close();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
return response;
Yes, this is pretty much expected http behaviour.
Options:
have a large timeout (you've already done this), and accept that it could take a long time to legitimately time out (as opposed to taking a while because of bandwidth)
maybe you can apply gzip on the request (and tell the server you're sending it compressed); I honestly don't know if this is supported automatically, but it could certainly be done by the api explicitly checking for a particular header and applying gzip decompression on the payload
change the api to perform a number of small uploads, and a completion message
live with it

Categories

Resources