I'm trying to make a single automated test that tests for decompression. But I've read online that visual studio automatically decompresses rest responses.
What I have:
public Response<TResponse> ExecuteRequest(IRestRequest request)
{
var response = RestClient.Execute(request);
var responseDto = (response.StatusCode == HttpStatusCode.OK) ? DeserializeResponse(response.Content) : DeserializeErrorResponse(response.Content);
return responseDto;
}
Where the rest client is the basic RestSharp rest client. But this doesn't return anything about the statistic of the call.
TestRequest.AddHeader("Content-Encoding", "gzip")
Doesn't work either :P
The responses are compressed through fiddler, but is there a way to automate testing this?
Related
Every time I send a request, the response says it had a 500 Server Error. However, I control both sides of this process, and the server is not erroring. Ideas?!
Here's how we setup the HttpClient to send the request. BTW, this Client is hosted in Microsoft's Dynamix CRM Online (in case that makes a difference):
client = new HttpClient();
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/javascript"));
And this is how we call it, from CRM Online, and get the response:
var task = client.PostAsyncSecurely("api/Invoices/CreateInvoice/", iHelper);
var result = task.GetAwaiter().GetResult();
Yes, we created our own extension, but all it does is convert the model we pass in to send across (and it's working, according to the receiving API).
public static Task<System.Net.Http.HttpResponseMessage> PostAsyncSecurely(this System.Net.Http.HttpClient client, string requestUri, System.Net.Http.ByteArrayContent content)
{
return client.PostAsync(requestUri, content);
}
We've tried creating responses multiple ways, in the Web API on our server, to no avail:
[HttpPost]
public HttpResponseMessage CreateInvoice([FromBody]Object invoiceHelper)
return Request.CreateResponse(HttpStatusCode.OK);
return new HttpResponseMessage(HttpStatusCode.OK);
return this.StatusCode(HttpStatusCode.OK);
To use Dynamics CRM Online WebAPI, you need to register your application as an allow app in teh Azure AD of your tenant (Microsoft Link)
The other way to connect to Dynamics CRM Online is using the SDK (if you are using a .NET Language) https://learn.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.messages.createrequest?view=dynamics-general-ce-9
Hope it helps
I am trying to send and receive process gzip-ed data from server on my client device application (not web).
I am sending gzip-ed content and on client side, I have following method that returns WebResponse:
protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse res = base.GetWebResponse(request);
if (((System.Net.HttpWebResponse)(res)).ContentEncoding.Contains("gzip"))
{
Stream responseStream = res.GetResponseStream();
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
}
//This returns g-ziped content as WebResponse, but I need to return
//above decompressed responseStream as WebResponse, how do I do that?
return res;
}
I am new to this but I am thinking that intercepting every response comming to my app in GetWebResponse is excellent centralized spot to decompress all responses. But the problem is how to pass the decompressed stream as response back?
Much appreciated
In our app (Silverlight 5 out-of-browser client hitting a WebApi server) we routinely use an HttpClient for posting/getting/deleting and so on all our entities between client and server. This all works fine most of the time, but recently we have run into an issue when uploading (posting) larger entities (> 30/35mb): we start the streaming process and BEFORE it is finished our Post method on the Web API is hit, receiving a null entity.
We can't understand what is going on, and suspect there must be some timing issue related since it all depends on the size of the upload.
To further explain, our client in summary is doing this:
HttpResponseMessage response = await _client.SendAsync(request);
string jsonResult = await response.Content.ReadAsStringAsync();
... where _client is our HttpClient and request our HttpRequestMessage. In case it is also relevant (I am trying not to flood the question with code :), the content in the request is created like this:
request.Content = new StringContent(JsonConvert.SerializeObject(content), Encoding.UTF8, "application/json");
Well, when we debug this the Post method on our server is hit before the await _client.SendAsync(request) finishes, which sort of "explains" why it is receiving a null entity in such cases (larger entities), where when it works that await call is finished and THEN the Post is hit.
In case if sheds more light into it, due to certain limitations on the HttpClient (regarding access to AllowWriteStreamBuffering), we have also tested an equivalent scenario but using directly an HttpWebRequest... unfortunately, the behavior is exactly the same. This is the relevant extract:
httpRequest.BeginGetRequestStream(RequestStreamCallback, httpRequest);
(where httpRequest is our HttpWebRequest with AllowWriteStreamBuffering = false), and the callback to handle the request stream is as follows:
private void RequestStreamCallback(IAsyncResult ar)
{
var request = ar.AsyncState as System.Net.HttpWebRequest;
if (request != null)
{
var requestStream = request.EndGetRequestStream(ar);
var streamWriter = new StreamWriter(requestStream) {AutoFlush = true};
streamWriter.Write(_jsonContent);
streamWriter.Close();
requestStream.Close(); // Belt and suspenders... shouldn't be needed
// Make async call for response
request.BeginGetResponse(ResponseCallback, request);
}
}
Again, for larger entities when we debug the Post method on the Web API is hit (with a null parameter) BEFORE the streamWriter.Write finalizes and the streamWriter.Close is hit.
We've been reading all over the place and fighting with this for days on now. Any help will be greatly appreciated!
In case somebody runs into this, I finally figured out what was going on.
In essence, the model binding mechanism in the Web API Post method was throwing an exception when de-serializing the JSON, but the exception was somewhat "hidden"... at least if you did not know that much about the inner workings of the Web API, as was my case.
My Post method originally lacked this validation check:
var errors = "";
if (!ModelState.IsValid)
{
foreach (var prop in ModelState.Values)
{
foreach (var modelError in prop.Errors.Where(modelError => modelError != null))
{
if (modelError.Exception != null)
{
errors += "Exception message: " + modelError.Exception.Message + Environment.NewLine;
errors += "Exception strack trace: " + modelError.Exception.StackTrace + Environment.NewLine;
}
else
errors += modelError.ErrorMessage + Environment.NewLine;
errors += " --------------------- " + Environment.NewLine + Environment.NewLine;
}
}
return Request.CreateErrorResponse(HttpStatusCode.NoContent, errors);
}
This is a "sample" check, the main idea being verifying the validity of the ModelState... in our breaking scenarios is wasn't valid because the Web API hadn't been able to bind the entity, and the reason could be found within the Errors properties of the ModelState.Values. The Post was being hit ok, but with a null entity, as mentioned.
By the way, the problem was mainly caused by the fact that we weren't really streaming the content, but using a StringContent which was attempted to be de-serialized in full... but that is another story, we were mainly concerned here with not understanding what was breaking and where.
Hope this helps.
I need to post data to server, and get compressed data back from it.
I am using windows phone 7 sdk.
I read that it can be done using SharpGIS or Coding4Fun toolkit.
They use WebClient (AFAIK).
can anyone help me?
Here's what I need to do-
Post data(XML) to url
Get compressed data (only GZip supported by server) in the form of xml string/stream
deserialise the xml data received
and the methods should be awaitable.
When I had to do this in wp7, I
Created a Portable Class Library project within my solution
Nuget the HTTP client library at https://www.nuget.org/packages/Microsoft.Net.Http (Install-Package Microsoft.Net.Http)
Nuget http://www.nuget.org/packages/Microsoft.Bcl.Async/ (Install-Package Microsoft.Bcl.Async ) and add to your PCL and UI solution
With in the portable class library
public class PostData
{
public async Task<T> TestMe<T>(XElement xml)
{
var client = new HttpClient(new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip
| DecompressionMethods.Deflate
});
var response = await client.PostAsync("https://requestUri", CreateStringContent(xml));
var responseString = await response.RequestMessage.Content.ReadAsStringAsync();
//var responseStream = await response.RequestMessage.Content.ReadAsStreamAsync();
//var responseByte = await response.RequestMessage.Content.ReadAsByteArrayAsync();
return JsonConvert.DeserializeObject<T>(responseString);
}
private HttpContent CreateStringContent(XElement xml)
{
return new StringContent(xml.ToString(), System.Text.Encoding.UTF8, "application/xml");
}
}
WebClient and HttpWebRequest for C4F toolkit are supported. HttpClient doesn't exist without http client library currently in WP.
I don't use Windows 8, which means Windows Phone SDK is only on VS 2010, which doesn't support the Microsoft HttpClient.
There's a NuGet package Delay.GZipWebClient written by an MS dev that adds simple support for it. So far it's worked like a charm.
http://blogs.msdn.com/b/delay/archive/2012/04/19/quot-if-i-have-seen-further-it-is-by-standing-on-the-shoulders-of-giants-quot-an-alternate-implementation-of-http-gzip-decompression-for-windows-phone.aspx
I've been racking my brain for a couple of days now on how to approach a new requirement.
I have two websites. The first one lets the user fill out an application. The second website is an internal website use to manage the users applications. I need to develop a "web service" that sends the application data from website 1 to website 2 and return a response to website 2 of success or failure. I have never done a web service before and I'm a bit confused on where to start. I've been reading various examples online but they all seem to be just a starting point for building a webservice... no specific examples.
So for posting the data website 1, what would my controller method look like? Do I use Json to post the data to website 2? What would and example of that look like? Is there some form of redirect in the method that points to website 2?
So for posting the response back to website 2 what would that controller method look like? I assume I would use Json again to send the response back to website 1? Is there some form of redirect in the method that points back to website 1?
I would use JSON and POST the application to the web service.
First I am assuming the application data is contained in some type of object. Use JSON.Net to serialize the object into JSON. It will look something like the following code.
var application = new Application();
string serializedApplication = JsonConvert.Serialize(application);
Second is to POST the code your endpoint(webservice, mvc action). To this you'll need to make a HTTPRequest to the endpoint. The following code is what I use to make to POST the code.
public bool Post(string url, string body)
{
//Make the post
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
var bytes = Encoding.Default.GetBytes(body);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
Stream stream = null;
try
{
request.KeepAlive = false;
request.ContentLength = bytes.Length;
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = -1;
request.Method = "POST";
stream = request.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
}
finally
{
if (stream != null)
{
stream.Flush();
stream.Close();
}
}
bool success = GetResponse(request);
return success;
}
public bool GetResponse(HttpWebRequest request)
{
bool success;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Created)
{
throw new HttpException((int)response.StatusCode, response.StatusDescription);
}
var end = string.Empty;
using (StreamReader reader = new StreamReader(responseStream))
{
end = reader.ReadToEnd();
reader.Close();
success = JsonConvert.DeserializeObject<bool>(end);
}
response.Close();
}
}
return success;
}
So now you have can POST JSON to an endpoint and receive a response the next step is to create the endpoint. The following code will get you started on an endpoint in mvc that will receive an application and process it.
[HttpPost]
public ActionResult SubmitApplication()
{
//Retrieve the POSTed payload
string body;
using (StreamReader reader = new StreamReader(Request.InputStream))
{
body = reader.ReadToEnd();
reader.Close();
}
var application = JsonConvert.Deserialize<Application>(body);
//Save the application
bool success = SaveApplication(application);
//Send the server a response of success or failure.
return Json(success);
}
The above code is a good start. Please note, I have not tested this code.
You have obviously more than one client for the data & operations. so a service is what you are looking for.
ASP.NET MVC is a good candidate for developing RESTful services. If you (and your Manager) are ready to use beta version, Then Checkout ASP.NET-Web API.
If you want to stay with a stable product, Go for MVC3. you may need to write some custom code to return the data in XML as well as JSON to server different kind of clients. There are some tutorials out there.
So create a Service (ASP.NET MVC / WCF Service) .You may then create 2 client apps, one for the external clients and another for the Internal users. Both of this apps can call methods in the Service to Create/ Read the user accounts / or whatever operation you want to do.
To make the apps more interactive and lively , you may conside including a wonderful thing called SiganalR, which helps you to get some real time data without continuosly polling the data base/ middle tier very in every n seconds !