I have a REST API implemented in microsoft Web API.
In my client i use HttpRequestMessage and HttpResponseMessage.
When i am sending a small class, I serialize it to JSON and then send it.
Soon, my class becomes bigger, and I need to JSON the class, zip it (in memory) and send to server. I can no longer use the same technique, I need to send the zip in chunks.
What is the proper way to achieve it ? I have read this post Posting a File and Associated Data to a RESTful WebService preferably as JSON
Need some good articles, I dont know where to start.
On the client side this should work pretty much out of the box...
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.TransferEncodingChunked = true;
var content = new CompressedContent(new StreamContent(new FileStream("c:\\big-json-file.json",FileMode.Open)),"UTF8");
var response = httpClient.PostAsync("http://example.org/", content).Result;
You can find an implementation of CompressedContent in WebApiContrib. If you are using earlier than .net 4.5 the request will be buffered client side before sending. Unfortunately the underlying HttpWebRequest doesn't support buffered streaming until .net 4.5
Related
I have a raw socket I want to make HTTP requests over. I would like to get back nicely-parsed-for-me http responses. Ideally I could feed this raw socket to HttpClient - something in a standard library. "TheWrapperClass" around the socket would allow me to use higher level instructions like again - the ones from HttpClient/HttpClientHandler like : clientHandler.ClientCertificates or clientHandler.Credentials etc.
Something like this maybe?:
HttpClientHandler clientHandler = new HttpClientHandler();
clientHandler.SocketFactory = mySocket/FactoryGoesHere???
HttpClient client = new HttpClient(new CustomMessageHandler());
var resp = await client.GetAsync("http://whatever");
I'm thinking of something like SSLSocketFactory from Java - is there an equivalent of this in .NET that I just haven't found yet?
At the end of the day - I really only want to have a library to invoke that writes HTTP to the wire easily and reads HTTP from the wire easily. If I had that I don't need HttpClient. Alternatively I need a way to use HttpClient to send bytes down the socket I give the class.
Edit:
I tried using a HttpMessageHandler but the HttpRespons is one that I hand craft. I need something that reads a stream and parses the http for me.
If you don't have a need for executing JavaScript, SimpleBrowser might fit for you:
https://github.com/SimpleBrowserDotNet/SimpleBrowser
It will not expose a raw socket for you to use as a bi-directional stream, but it will allow you to navigate via HTTP and receive an HTTP response. The HTTP response can either be the raw text response from the web server, or an parsed XML (XHTML) document.
I have Managed to Setup II7 with Gzip Compression .
I can check via web sniffer that my asmx web service encoding is Gzip but how to i enable
gzip Compression on my C# Client , i am using the Web Service is Service reference in my application.
Actually i am trying to send large amount of data , 10k objects of array so Compression with be great effect on bw.
but how do I enable Compression on my C# Client.
i am trying to see that many people sees same problem but there nothing clear answer some says use third party tools or some says about custom headers etc etc .
is not there any proper way , built in to consume Compressed web service
As #Igby Largeman pointed out, you can use your IIS7 to enable the compression on the server, but this is not enough.
The main idea is to set the headers on the client side and server side:
Client:
Accept-Encoding = "gzip, deflate";
You can achieve this by code:
var request = HttpWebRequest.Create("http://foofoo");
request.Headers["Accept"] = "application/json";
request.Headers["Accept-Encoding"] = "gzip, deflate";
or
var request = HttpWebRequest.Create("http://foofoo");
request.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate;
If you use some WCF client, and not the HttpWebRequest, you should use custom inspector and dispatcher, like in this article:
So I used a message inspector implementing IClientMessageInspector and IDispatchMessageInspector to automatically set the AcceptEncoding and ContentEncoding http headers.
This was working perfectly but I could not achieve to decompress the response on the server by first detecting the ContentEncoding header thus I used the work around to first try to decompress it and if it fails just try to process the request as normal.
I also did this in the client pipeline and this also works.
Server:
// This is the nearly same thing after all
Content-Encoding = "gzip" OR Content-Encoding = "deflate"
To do this on the Server side, you should enable httpCompression in the IIS.
I think you should check the original article to get this work
There is a web service that can only be consumed via http and a client that can only consume https web services. Therefore I need some intermediary that forwards on requests received in https and returns responses in http.
Supposing that the intermediary is completely dumb save for the fact that it knows where the web service endpoint is (i.e. it doesn't know what the signature of the service is, it just knows that it can communicate with it via an http web request, and it listens on some https uri, forwarding on anything it receives), what is the most simple way of achieving this?
I've been playing around with this all day and am not sure how to achieve the "dumb" bit, i.e. not knowing the signature for passing back the verbatim response.
A dumb intermediary is essentially a proxy. Your best bet might to be just use standard asp.net pages (instead of shoehorning into service functionality like ASMX or WCF which are just going to fight you) so you can receive the request exactly as-is and process it in a simple way using standard request/response. You can make use of HttpWebRequest class to forward the request on to the other endpoint.
Client requests https://myserver.com/forwarder.aspx?forwardUrl=http://3rdparty.com/api/login
myserver.com (your proxy) reads querystring forwardUrl and any POST or GET request included.
myserver.com requests to http://3rdparty.com/api/login and passes along GET or POST data sent from the client.
myserver.com takes response and sends back as response to other endpoint (essentially just Response.Write contents out to the response)
You would need to write forwarder.aspx to process the requests. Code for forwarder.aspx would be something like this (untested):
protected void Page_Load(object sender, EventArgs e)
{
var forwardUrl = Request.QueryString["forwardUrl"];
var post = new StreamReader(Request.InputStream).ReadToEnd();
var req = (HttpWebRequest) HttpWebRequest.Create(forwardUrl);
new StreamWriter(req.GetRequestStream()).Write(post);
var resp = (HttpWebResponse)req.GetResponse();
var result = new StreamReader(resp.GetResponseStream).ReadToEnd();
Response.Write(result); // send result back to caller
}
As part of learning node.js, I just created a very basic chat server with node.js and socket.io. The server basically adds everyone who visits the chat.html wep page into a real time chat and everything seems to be working!
Now, I'd like to have a C# desktop application take part in the chat (without using a web browser control :)).
What's the best way to go about this?
I created a socket server in nodejs, and connected to it using TcpClient.
using (var client = new TcpClient())
{
client.Connect(serverIp, port));
using (var w = new StreamWriter(client.GetStream()))
w.Write("Here comes the message");
}
Try using the HttpWebRequest class. It is pretty easy to use and doesn't have any dependencies on things like System.Web or any specific web browser. I use it simulating browser requests and analyzing responses in testing applications. It is flexible enough to allow you to set your own per request headers (in case you are working with a restful service, or some other service with expectations of specific headers). Additionally, it will follow redirects for you by default, but this behavior easy to turn off.
Creating a new request is simple:
HttpWebRequest my_request = (HttpWebRequest)WebRequest.Create("http://some.url/and/resource");
To submit the request:
HttpWebResponse my_response = my_request.GetResponse();
Now you can make sure you got the right status code, look at response headers, and you have access to the response body through a stream object. In order to do things like add post data (like HTML form data) to the request, you just write a UTF8 encoded string to the request object's stream.
This library should be pretty easy to include into any WinForms or WPF application. The docs on MSDN are pretty good.
One gotcha though, if the response isn't in the 200-402 range, HttpWebRequest throws an exception that you have to catch. Fortunately you can still access the response object, but it is kind of annoying that you have to handle it as an exception (especially since the exception is on the server side and not in your client code).
I have a WCF service hosted that is returning a byte[] of protobuf-net serialized data. Originally this was hosted over the default webHttpBinding settings (SOAP) and everything was working properly. I recently found out that I need to call HTTP GETs and POSTs directly from our client so I thought it'd be easier to switch to use a RESTful service. I switched to use the WebGet attribute and the WCF REST Template.
I attempted to create a simple web site to test the client and I'm having trouble deserializing the data. This is an example of how I'm calling the service:
using (WebClient client = new WebClient())
{
result = client.DownloadString(url);
}
// Deserialize
BinaryVehicles binVehs;
using (var ms = new MemoryStream(StrToByteArray(result)))
{
binVehs = Serializer.Deserialize<BinaryVehicles>(ms);
}
An example of what is returned in "result":
< base64Binary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">ChsKCzEyMy00NTYtNzg5EgU0NDAwMBoFQmxhY2sKHAoLOTYzLTg1Mi03NDESBTIzMDAwGgZTaWx2ZXI=< /base64Binary>
I also attempted to deserialize the data between the < base64Binary > tags with no results. Does anyone have any idea on how I should go about sending the binary protobuf-net data from an WebGet method and how I should deserialize the data? Thanks.
protobuf-net primarily handles just the serialization aspects (the protobuf spec by Google doesn't define any further than this). So it really comes down to: how are you serializing it?
I must admit that the WCF GET approach is not something I've looked at hugely, so there is no special handling there. One simple approach may be to look at just returning a string, and handling the base-64 encoding yourself, but to be honest if you are doing HTTP GET, then WCF itself seems overkill.
I blogged here about using ASP.NET MVC at the server for protobuf via HTTP GET. The linked sample code also includes a wire-compatible ASP.NET implementation.
If there is something appropriate we can do to make WCF GET easier, I'm all ears...