Exception in callback trying to get WebResponse - httpwebrequest

I am using HttpWebRequest to transfer files. The workflow looks like this:
webRequest.BeginGetRequestStream(new AsyncCallback(WriteToStreamCallback), webRequest);
In WriteStreamToCallback:
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
Stream requestStream = webRequest.EndGetRequestStream(asynchronousResult);
Write bytes to the requestStream, then call:
webRequest.BeginGetResponse(new AsyncCallback(ReadHttpResponseCallback), webRequest);
The exception occurs in ReadHttpResponseCallback:
HttpWebRequest webRequest = (HttpWebRequest)asynchronousResult.AsyncState;
// The next line throws a WebException
HttpWebResponse webResponse = (HttpWebResponse)webRequest.EndGetResponse(asynchronousResult);
The exception is:
A first chance exception of type 'System.Net.WebException' occurred in
System.Windows.dll
The remote server returned an error: NotFound.
Can the app recover from this? What might be the cause? It is intermittent; is it a timing issue?
Thanks for any insight...
UPDATE:
private void ReadHttpResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest webRequest = (HttpWebRequest) asynchronousResult.AsyncState;
// The next line throws the exception
HttpWebResponse webResponse = (HttpWebResponse) webRequest.EndGetResponse(asynchronousResult);
/* SNIP */
}
catch (WebException webEx)
{
System.Diagnostics.Debug.WriteLine(string.Format(" {0} {1}", "ReadHttpResponseCallback - WebException", webEx.Message));
}
catch (Exception xx)
{
System.Diagnostics.Debug.WriteLine(string.Format("{0} {1}", "ReadHttpResponseCallback", xx.Message));
}
}

May have found a solution here: http://fearthecowboy.com/2011/09/02/fixing-webrequests-desire-to-throw-exceptions-instead-of-returning-status/

Related

httpwebrequest is not waiting for my response

I have a JavaScriptHelper class with a custom WebPost method as follows:
public string WebPost(string url, string json)
{
#region
string responseData = "";
try
{
HttpWebRequest webRequest = System.Net.WebRequest.Create(url) as HttpWebRequest;
StreamWriter requestWriter = null;
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
using (requestWriter = new StreamWriter(webRequest.GetRequestStream()))
{
requestWriter.Write(json);
}
using (StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream()))
{
responseData = responseReader.ReadToEnd();
}
webRequest = null;
}
catch (WebException ex)
{
LogBase.LogController.WriteError(ex);
}
catch (Exception ex)
{
LogBase.LogController.WriteError(ex);
}
return responseData;
#endregion
}
I use this to send a POST request to an ASP.NET WebAPI service as follows:
RegisterModel model = new RegisterModel();
model.email = "abc#gmail.com";
model.oAuthId = "11111111";
model.oAuthType = "Facebook";
string jsonStr = JsonConvert.SerializeObject(model);
string response = new JavaScriptHelper().WebPost("http://localhost:9091/api/Authentication/authenticateoauth", jsonStr);
The service receives this call. If the user exists, it returns the response, if it doesnt, it creates the user and returns the response.
The problem I am facing is that when the user exists, everything works fine. I get the response on the client (JSON). When it doesn't exists, it creates the user correctly on the server, but my client breaks off early and doesn't wait for a response. I get the following error:
System.Net.WebException was unhandled
HResult=-2146233079
Message=The remote server returned an error: (500) Internal Server Error.
Source=System
StackTrace:
at System.Net.HttpWebRequest.GetResponse()
How can I force my request to wait for a response a little longer?

2 exceptions when trying to make async HttpWebRequest

I am writing an MVC Web API the make async HttpWebRequest calls. I am getting 2 different exceptions. Below is the method I am using.
The 1st exception is: "This stream does not support seek operations." and it is happening on the responseStream.
The 2nd exception is: "timeouts are not supported on this stream" and that is happening on the MemoryStream content.
What am I doing wrong? I have been Googling but not really finding any solution.
Thanks,
Rhonda
private async Task GetHtmlContentAsync(string requestUri, string userAgent, string referrer, bool keepAlive, TimeSpan timeout, bool forceTimeoutWhileReading, string proxy, string requestMethod, string type)
{
//string to hold Response
string output = null;
//create request object
var request = (HttpWebRequest)WebRequest.Create(requestUri);
var content = new MemoryStream();
request.Method = requestMethod;
request.KeepAlive = keepAlive;
request.Headers.Set("Pragma", "no-cache");
request.Timeout = (Int32)timeout.TotalMilliseconds;
request.ReadWriteTimeout = (Int32)timeout.TotalMilliseconds;
request.Referer = referrer;
request.Proxy = new WebProxy(proxy);
request.UserAgent = userAgent;
try
{
using (WebResponse response = await request.GetResponseAsync().ConfigureAwait(false))
{
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
await responseStream.CopyToAsync(content);
}
}
var sr = new StreamReader(content);
output = sr.ReadToEnd();
sr.Close();
}
}
catch (Exception ex)
{
output = string.Empty;
var message = ("The API caused an exception in the " + type + ".\r\n " + requestUri + "\r\n" + ex);
Logger.Write(message);
}
return output;
}
I fixed the issue by adding
content.Position = 0
before new StreamReader line. Now I just need to get it work with GZip compression.
Rhonda

How to return the error message to WCF service generated in Message Inspector with Schema Validation

void validateMessage(ref System.ServiceModel.Channels.Message message)
{
XmlDocument bodyDoc = new XmlDocument();
var body = message.GetReaderAtBodyContents();
bodyDoc.Load(body);
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas = schemas;
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
XmlReader reader = XmlReader.Create(new XmlNodeReader(bodyDoc), settings);
while (reader.Read()) ; // do nothing, just validate
// Create new message
Message newMsg = Message.CreateMessage(message.Version, null,
new XmlNodeReader(bodyDoc.DocumentElement));
newMsg.Headers.CopyHeadersFrom(message);
foreach (string propertyKey in message.Properties.Keys)
newMsg.Properties.Add(propertyKey, message.Properties[propertyKey]);
// Close the original message and return new message
message.Close();
message = newMsg;
}
private static void ValidationCallBack(object sender, ValidationEventArgs e)
{
Console.WriteLine("Validation Error: {0}", e.Message);
//throw new RequestValidationFault(e.Message);
throw new FaultException<string>(e.Message);
}
object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
try
{
validateMessage(ref request);
}
catch (FaultException e)
{
throw new FaultException<string>(e.Message);
}
return null;
}
The above code screenshot help me validate message requested from client against the schema and throw the errors if some inconsistency happen. But I don't know how to pass error message back to the WCFservice since I also would like to return the error message to the client.
I tried to add the error message to request message and return to WCF service. But I have no idea on how to put the error message to its parent element in the body content which is easy for me to get it in the service operation. Thanks in advance!

ProtocolError while calling HttpWebRequest.GetResponse()

I have a page containing links to some files.
I basically need to access the source of the page for parsing it then and obtaining all the hyperlinks to the files.
My code is something like this (some piece of code I've found in many places on the net ..):
"private static byte[] ReadImageFromUrl(string url)
{
var myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Timeout = 10000;
WebResponse myResp = myReq.GetResponse();
Stream stream = myResp.GetResponseStream();
List<byte> bytesList = new List<byte>();
using (var br = new BinaryReader(stream))
{
try
{
while (true)
{
var b = br.ReadByte();
bytesList.Add(b);
}
}
catch (Exception)
{}
br.Close();
}
myResp.Close();
return bytesList.ToArray();
}"
Now the problem is I get "System.Net.WebException: The remote server returned an error: (500) Internal Server Error." when calling "myReq.GetResponse()" - examining the error I see that the status is 'ProtocolError'.
The response property of the WebException object contains some server error ..(although when opening it from the browser it opens correctly) ...also when I call this function with the url of one of my files I get the same ProtocolError status, but the 404 error ...
Please give any hint how could I solve it... or any other possibility of accomplishing this task.
Thanks !
My new code after using Fiddler is:
private static byte[] ReadFileFromUrl(string url)
{
var myReq = (HttpWebRequest)WebRequest.Create(url);
myReq.Accept = const_AcceptHeader;
myReq.Headers.Set(const_AcceptLanguageHeaderName, const_AcceptLanguageHeader);
myReq.UserAgent = const_AcceptUserAgentHeader;
myReq.CookieContainer = new CookieContainer();
myReq.KeepAlive = true;
myReq.Timeout = Int32.Parse(ConfigSettings.RequestPageTimeout) * 1000;
WebResponse myResp = null;
List<byte> bytesList = null;
myResp = myReq.GetResponse();
Stream stream = myResp.GetResponseStream();
bytesList = new List<byte>();
using (var br = new BinaryReader(stream))
{
try
{
while (true)
{
var b = br.ReadByte();
bytesList.Add(b);
}
}
catch (Exception ex)
{
throw;
}
br.Close();
}
return bytesList.ToArray();
}
All variables that start with const_ are taken from Fiddler.
Well, I solved that using Fiddler ... I passed to my request object the headers as I have seen them in Fiddler ...& it worked, no error

Accessing HTTP status code while using WCF client for accessing RESTful services

Thanks to this answer, I am now able to successfully call a JSON RESTful service using a WCF client. But that service uses HTTP status codes to notify the result. I am not sure how I can access those status codes since I just receive an exception on client side while calling the service. Even the exception doesn't have HTTP status code property. It is just buried in the exception message itself.
So the question is, how to check/access the HTTP status code of response when the service is called.
As a quick win, you can access the status code in the exception like this:
try
{
client.DoSomething(); // call the REST service
}
catch (Exception x)
{
if (x.InnerException is WebException)
{
WebException webException = x.InnerException as WebException;
HttpWebResponse response = webException.Response as HttpWebResponse;
Console.WriteLine("Status code: {0}", response.StatusCode);
}
}
Maybe there's a solution with a message inspector. But I haven't figured it out yet.
A solution without WCF would be to use the HttpRequest and DataContractJsonSerializer classes directly:
private T ExecuteRequest<T>(Uri uri, object data)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
// If we have data, we use a POST request; otherwise just a GET request.
if (data != null)
{
request.Method = "POST";
request.ContentType = "application/json";
DataContractJsonSerializer serializer = new DataContractJsonSerializer(data.GetType());
Stream requestStream = request.GetRequestStream();
serializer.WriteObject(requestStream, data);
requestStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
Stream responseStream = response.GetResponseStream();
T result = (T)deserializer.ReadObject(responseStream);
responseStream.Close();
response.Close();
return result;
}