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
Related
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
This ServiceStack client code works:
var client = new JsonServiceClient("http://localhost:32949/test");
var request = new MyRequest { ClassificationId = new ClassificationId (21300) };
var response = client.Post(request);
However, when observing the traffic in Fiddler, I see nothing. I would like to observe the traffic to get a better idea on how to build the required JSON request for other clients I have to write.
To make the above code work, I had to reference the assembly that has the service, and I am suspecting that ServiceStack is making some clever calls to avoid sending a HTTP request. Is this the case ?
Why am I not seeing any traffic in Fiddler, and how do I force it ?
HTTP traffic to localhost endpoints via the browser is shown correctly.
Edit your hosts file, located at
C:\Windows\System32\drivers\etc\hosts
and add the following entry
127.0.0.1 mymachine.com
then point your client to mymachine.com instead of localhost
I will answer my own question here - commenter #wal pointed out the problem to me:
This has nothing to do with ServiceStack, and requests actually go over the http protocol. The problem was looping back to localhost did not send the traffic through fiddler. It is actually explained on the Fiddler2 FAQ page.
The other trick is to replace your "localhost" uri with your machine name, and that should work out of the box with Fiddler.
http://machinename:port/test
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 hosted my WCF REST Service in IIS6. But when I try to consume any method, it gives me an error 400.
However when I use the same url in IE, the desired response is achieved. How come I can't consume it in my client while I can hit it directly in IE.
Following is the Client code :
string xmlInputValue = XMLUtility<string>.GetDataContractXml("Testing", null);
WebClient wc = new WebClient();
wc.Headers["Content-Type"] = "application/octet-stream";
xmlInputValue = string.Empty;
byte[] buf = new byte[0x10000];
wc.UploadString(new Uri(#"http://localhost/FileUpload/UploadData/PingTest/?123"), "POST", "4567");
Got the answer. While using IIS for hosting the service, endpoint address should be blank
One quick question, why are you setting Content-type as "application/octet-stream"? are you sure service binding is expecting the same content-type. Anyways, I'd capture Fiddler trace (using fiddler tool: http://fiddler2.com) for IE (success scenario) and check how request is sent by IE which is accepted by service and compare with request sent by client application.
HTH,
Amit