Retrieve Response Headers in Silverlight? - silverlight

I'm issuing a HttpWebRequest in silverlight and attempting to read (amongst other things) the headers in the response. Unfortunately, while I can get the response object (HttpWebResponse) any attempt to access the Headers collection results in a "not implemented" exception. Any ideas of how to do this? I'm attempting to pull a large recordset from azure (~8k rows) and need to check the response header for the continuation token.

Thanks to #silverfighter, I have the answer. The trick was to tell SilverLight 3 to let the client (.NET) handle the call rather than the browser (the default). Once you do this, you have access to the response headers both via the WebClient and HttWebRequest approaches. More information here:
http://blogs.msdn.com/carlosfigueira/archive/2009/08/15/fault-support-in-silverlight-3.aspx
http://msdn.microsoft.com/en-us/library/dd470096(VS.95).aspx
http://blogs.msdn.com/silverlight_sdk/archive/2009/08/12/new-networking-stack-in-silverlight-3.aspx

The HttpWebRequest does not permit access to the response headers collection. Use the WebClient instead, which exposes a WebResponse.Headers property.

Unfortunately, while that property exists, it similarly returns a Not Implemented Exception.
I'm having a hard time believing that this is as difficult as it seems... I would imagine that many have the same requirement.

Response Headers are not supported in Browser Http Handling.
You must specify Client Http Handling before calling your HttpHandler:
bool httpResult = WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(...);
The result headers will now be available on webClient object in the wc_OpenReadCompleted method.
Have a look at: http://msdn.microsoft.com/en-us/library/dd920295(v=vs.95).aspx

Related

How to get Content-Length from response headers in CN1?

I implemented this but the response headers don't include Content-Length, even though I make sure the server replies that bit specifically. I also verified the response outside CN1 and it includes Content-Length. The full list of headers captured in ReadHeaders is (as seen from Android): null,Alt-Svc,Cache-Control,Connection,Content-Type,Date,ETag,Server,Transfer-Encoding,Vary,X-Android-Received-Millis,X-Android-Response-Source,X-Android-Selected-Protocol,X-Android-Sent-Millis,X-Cloud-Trace-Context,X-Powered-By. Right now to estimate download sizes I (1) call endpoint to get total size (2) call endpoint to get actual download and use NetworkManager progress listener, but it would be nice to be able to track progress with only one request (by using Content-Length). The vanilla RequestBuilder doesn't expose response headers so a direct usage of ConnectionRequest with readHeaders is needed. But the Content-Length is missing from getHeaderFieldNames
Note:
The reason why this wasn't working is because by default Android/CN1 sends a request with the header Accept-Enconding:gzip. This returns a chunked response that doesn't include the length header. I can't guarantee that this behavior matches every server response, but it does in my case (Node.js + Express)
To force a server to return a non-chunked response, set the header to "compress", "identity", or "deflate"
Example:
Rest.post(url).header("Accept-Encoding", "compress").fetchAsJsonMap(resp -> {...

What is the size limit of email body in messages.send method of Gmail API?

I am using official .net api client to send emails with attachments by messages.send method. When I attach a file of size more than approximately 5mb, I've come to
[JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.]
Newtonsoft.Json.JsonTextReader.ParseValue() +1187
Newtonsoft.Json.JsonTextReader.ReadInternal() +65
Newtonsoft.Json.JsonTextReader.Read() +28
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) +237
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) +783
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) +293
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) +274
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, JsonSerializerSettings settings) +57
Google.Apis.Json.NewtonsoftJsonSerializer.Deserialize(String input) in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis.Core\Apis\Json\NewtonsoftJsonSerializer.cs:120
Google.Apis.Services.<DeserializeError>d__8.MoveNext() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\Services\BaseClientService.cs:286
[GoogleApiException: An Error occurred, but the error response could not be deserialized]
Google.Apis.Requests.ClientServiceRequest`1.Execute() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\Requests\ClientServiceRequest.cs:102
I think client use Metadata URI, for metadata-only requests. A am going to try another option: Upload URI, for media upload requests.
It looks like there is a limit on email size that leads to exception of parsing error response in the client library.
So, the first question: is there a size limit?
Second, there is no info about how to use different upload methods via client, do you know any client library documentation?
Update: I hacked that request produced by
var request = gmailService.Users.Messages.Send(message, AccountUserId);
is going to https://www.googleapis.com/gmail/v1/users/me/messages/send. As I supposed it didn't use media upload request.
I ended up with limit on attachments total size. Here is code snippet.
Class level:
public const int MaxAttachmentsSize = 5 * 1024 * 1024;
Method level:
var attachmentsSize = 0;
foreach (var attachment in attachments)
{
attachmentsSize += attachment.Item1;
if (attachmentsSize > MaxAttachmentsSize) break;
mailMessage.Attachments.Add(attachment.Item2);
}
There is limit in MB of whole message. Google API allows you for quite big email but it may get timeout when sending if your service because of connection speed will be doing it too long.
According to this google docs it is 35MB:
google api send docs
For anything (uploading) over a few MB you should definitely use the /upload version of the method, otherwise yes you may run into those size limitations.
In response to the second part of your question...
Second, there is no info about how to use different upload methods via client, do you know any client library documentation?
I did a little poking around in the API, and I see that there is also a method that takes a stream as the 3rd parameter.
services.Users.Messages.Send( body, userId, stream, contentType)
Digging into the source code of that, I see that it seems to use a URL that looks like:
upload/....
I haven't tried it yet, and I don't know (yet) what it wants for a "stream", but this looks like a good possibility for getting a resumable upload with a bigger limit.

How to set http header If-Modified-Since on a WebRequest in Windows Phone 7?

Trying to set the 'If-Modified-Since' header in wp7:
request.Headers[HttpRequestHeader.IfModifiedSince] = dateString;
Gives the error:
This header must be modified with the appropriate property.
Which means that the property .IsModifiedSince should be used on the request class, as described in MSDN: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.ifmodifiedsince.aspx
But this property does not exist in Silverlight i.e. WP7.
Has anyone been able to set this header for a http request on Windows Phone 7?
Shawn Wildermuth posted this problem back in September 2010, with no solution:
http://social.msdn.microsoft.com/Forums/en/windowsphone7series/thread/8aec7481-2cf3-4047-b0d4-05d4313a9e4c
Thank you!
You can just use the string that HttpRequestHeader.IfModifiedSince represents:
request.Headers["If-Modified-Since"] = dateString;
I've had to do this with a number of other headers which WP7 doesn't expose helper methods for setting.
Update
Based on the remarks at http://msdn.microsoft.com/en-us/library/8y7x3zz2(v=VS.95).aspx it would appear that it is not possible to set this header in WP7.
As an alternative you could create your own proxy server to handle the caching for your app.
This can only be set on the HTTPWebRequest object so casting the WebRequest should allow you to set the property eg:
((HttpWebRequest)request).IfModifiedSince = modifiedDate;
It takes a DateTime object so you may need to parse the string first.
The short answer is: It cannot be done, not supported.
Solution would be, as Matt Lacey states, to create a proxy class to handle this.
That proxy would set
request.AllowStreamReadBuffering = false;
and then parse the response until the header ends or the header value has been found.
Note! This workaround limits the data downloaded to the phone, but not the work needed by the server to process the request.
request.Headers.Add("If-Modified-Since", datestring);

Silverlight 4.0 - HttpWebRequest throwing ProtocolViolationException

I am getting a "System.Net.ProtocolViolationException: Operation is not valid due to the current state of the object." error when trying to call
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.ContentType = "text/xml";
request.BeginGetRequestStream(RequestCompleted, request);
I suspect this may be because you are performing a BeginGetRequestStream on a request object for which you have specified the "GET" method.
When performing a "GET" the server will not be expecting an entity body in the request hence you should proceed straight to BeginGetResponse. Also specifying a ContentType on the request is not necessary, it specifies the type of content being sent in the entity body of the request but as stated a "GET" doesn't send any content it only gets content.
I disagree with AnthonyWJones answer. I find nothing in the HTTP spec that prohibits a "GET" request from containing a message body. I think this has unfortunately become the de facto understanding of how HTTP works since there is generally no need (or way) to include a message body. Having said that, he is correct as to the cause of this specific exception. However, I think the BCL should be changed to allow it.
If anyone can point it out I would be very interested to know where the spec precludes this:
HTTP RFC 2616

Specified method is not supported httpwebrequest - Silverlight

I am trying to use an HttpWebRequest object in Silverlight 2.0, to do a "POST".
Upon return from the BeginGetStream method I end up with the following error :
Message: "Specified method is not supported."
StackTrace: " at System.Net.BHWRAsyncResult.get_AsyncWaitHandle()"
Here's some sample code: Note I have used fiddler to see if anything is being sent across the wire and there is no network activity.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri("http://someurl"));
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.Accept = "text/plain, */*";
req.Headers["X-Requested-With"] = "XMLHttpRequest";
AsyncCallback callBack = new AsyncCallback(streamResponse);
req.BeginGetRequestStream(callBack, null);
Thanks,
Dave
I just found one solution for this problem. HTTP Client need to know Content-Length to fill the Content-Length HTTP header value. Client can'not start request before it length became known. When You get RequestStream WebRequest can'not know how much bytes you will send to server. You must Close stream to commit Content-Length and only after closing the RequestStream You can call BeginGetResponse. It is strange that this not done inside WebRequest.
Hope this helps,
Dmitry
I just ran into this a while ago. Off the top of my head:
1) clientaccesspolicy.xml / crossdomain.xml isn't around on the server you are calling. Like flash, silverlight won't talk to a domain that doesn't have one.
1.1) Does fiddler log 404 errors? If it doesn't, you won't see the failed attempts Silverlight is making trying to get those policy files.
2) Failing that, sending your custom header might be upsetting things.

Resources