I've attempted to send a POST request on a Windows Store App. And I've attempted to use Fiddler or Charles to capture it.
Here is my attempt:
Uri uri = new Uri("http://example.com");
using (StringContent content = new StringContent("{}", Encoding.UTF8, "application/json"))
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Host = uri.Host;
try
{
using (HttpResponseMessage response = await client.PostAsync(uri, content))
{
if (response.IsSuccessStatusCode)
{
String result = await response.Content.ReadAsStringAsync();
return result;
}
return null;
}
}
catch (Exception ex)
{
return null;
}
}
}
Why I am unable to use fiddler or Charles to analyze the traffic? Here is the exception I get:
Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
HelpLink null string
HResult -2146233088 int
InnerException {"The underlying connection was closed: Unable to connect to the remote server."} System.Exception {System.Net.WebException}
IPForWatsonBuckets 206848215 System.UIntPtr
IsTransient false bool
Message "An error occurred while sending the request." string
RemoteStackTrace null string
Source "mscorlib" string
StackTrace " at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()\r\n at Example.Services.ExampleServices.<ExampleClass>d__3.MoveNext() in c:\\TFS\\Example\\ExampleMain\\Example\\Services\\ExampleServices.cs:line 110" string
TargetSite {Void Throw()} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
WatsonBuckets null object
I found the origin of the issue and the solution: the Host header mustn't be manually defined for a request to work in an environment where Fiddler or Charles is active.
Which means we have to remove or comment-out the following line:
client.DefaultRequestHeaders.Host = uri.Host;
By not setting the Host youself, magically your app will be working again with a local proxy, and the framework will set the Host header fine by itself.
This will be useful for people who might have followed this recent Microsoft's guide where they do it wrong: http://blogs.msdn.com/b/wsdevsol/archive/2013/02/05/how-to-use-httpclient-to-post-json-data.aspx