Uploading data with HttpClient using a "push" model

Very poorPoorAverageGoodExcellent (1 votes) 
Loading ... Loading ...

If you have used the HttpWebRequest class to upload data, you know that it uses a “push” model. What I mean is that you call the GetRequestStream method, which opens the connection if necessary, sends the headers, and returns a stream on which you can write directly.

.NET 4.5 introduced the HttpClient class as a new way to communicate over HTTP. It actually relies on HttpWebRequest under the hood, but offers a more convenient and fully asynchronous API. HttpClient uses a different approach when it comes to uploading data: instead of writing manually to the request stream, you set the Content property of the HttpRequestMessage to an instance of a class derived from HttpContent. You can also pass the content directly to the PostAsync or PutAsync methods.

The .NET Framework provides a few built-in implementations of HttpContent, here are some of the most commonly used:

  • ByteArrayContent: represents in-memory raw binary content
  • StringContent: represents text in a specific encoding (this is a specialization of ByteArrayContent)
  • StreamContent: represents raw binary content in the form of a Stream

For instance, here’s how you would upload the content of a file:

async Task UploadFileAsync(Uri uri, string filename)
{
    using (var stream = File.OpenRead(filename))
    {
        var client = new HttpClient();
        var response = await client.PostAsync(uri, new StreamContent(stream));
        response.EnsureSuccessStatusCode();
    }
}

As you may have noticed, nowhere in this code do we write to the request stream explicitly: the content is pulled from the source stream.

This “pull” model is fine most of the time, but it has a drawback: it requires that the data to upload already exists in a form that can be sent directly to the server. This is not always practical, because sometimes you want to generate the request content “on the fly”. For instance, if you want to send an object serialized as JSON, with the “pull” approach you first need to serialize it in memory as a string or MemoryStream, then assign that to the request’s content:

async Task UploadJsonObjectAsync<T>(Uri uri, T data)
{
    var client = new HttpClient();
    string json = JsonConvert.SerializeObject(data);
    var response = await client.PostAsync(uri, new StringContent(json));
    response.EnsureSuccessStatusCode();
}

This is fine for small objects, but obviously not optimal for large object graphs…

So, how could we reverse this pull model to a push model? Well, it’s actually pretty simple: all you have to do is to create a class that inherits HttpContent, and override the SerializeToStreamAsync method to write to the request stream directly. Actually, I intended to blog about my own implementation, but then I did some research, and it turns out that Microsoft has already done the work: the Web API 2 Client library provides a PushStreamContent class that does exactly that. Basically, you just pass a delegate that defines what to do with the request stream. Here’s how it works:

async Task UploadJsonObjectAsync<T>(Uri uri, T data)
{
    var client = new HttpClient();
    var content = new PushStreamContent((stream, httpContent, transportContext) =>
    {
        var serializer = new JsonSerializer();
        using (var writer = new StreamWriter(stream))
        {
            serializer.Serialize(writer, data);
        }
    });
    var response = await client.PostAsync(uri, content);
    response.EnsureSuccessStatusCode();
}

Note that the PushStreamContent class also provides a constructor overload that accepts an asynchronous delegate, if you want to write to the stream asynchronously.

Actually, for this specific use case, the Web API 2 Client library provides a less convoluted approach: the ObjectContent class. You just pass it the object to send and a MediaTypeFormatter, and it takes care of serializing the object to the request stream:

async Task UploadJsonObjectAsync<T>(Uri uri, T data)
{
    var client = new HttpClient();
    var content = new ObjectContent<T>(data, new JsonMediaTypeFormatter());
    var response = await client.PostAsync(uri, content);
    response.EnsureSuccessStatusCode();
}

By default, the JsonMediaTypeFormatter class uses Json.NET as its JSON serializer, but there is an option to use DataContractJsonSerializer instead.

Note that if you need to read an object from the response content, this is even easier: just use the ReadAsAsync<T> extension method (also in the Web API 2 Client library). So as you can see, HttpClient makes it very easy to consume REST APIs.

Little known new features in Visual Studio 2012

Very poorPoorAverageGoodExcellent (8 votes) 
Loading ... Loading ...

Visual Studio 2012 RC is out since last week, and even though I didn’t have much time to play with it yet, I think I like it so far. Lots of things have already been said about the design, and about the most important new features, but there are also many smaller and less remarkable improvements that make life easier for us. Since I have seen little or nothing written about those, I thought I would make a list of what I noticed so far.

Better Edit and Continue: improved debug experience with anonymous methods

Edit and continue is a very useful feature that has been present in Visual Studio for a long time. It’s great when you need to fix some code in the middle of a step-by-step debugging session without restarting the application completely. This feature has always had a limitation: you couldn’t use it in a method that contained an anonymous method:

Modifying a ’method’ which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled.

Before .NET 3.5, it wasn’t really a problem since anonymous methods were not very common, but since Linq was introduced and lambda expressions became more widely used, this limitation began to grow more and more annoying.

Well, good news: Visual Studio 2012 fixed that! You can now use Edit and Continue in a method that contains lambda expressions or Linq queries. Note that the limitation hasn’t completely disappeared: you still can’t modify a statement that contains an anonymous method. Note the slightly different error message:

Modifying a statement which contains a lambda expression will prevent the debug session from continuing while Edit and Continue is enabled.

But you can modify everything else in the method body, which is a great improvement. Note that editing a method that contains anonymous types is also supported, as long as you don’t modify the anonymous type itself.

Optimized event handler autocompletion

Visual Studio has a nice autocompletion feature that allow you to generate an event handler automatically when you type += and Tab after an event name :

image

But the new EventHandler(…) part is redundant, because since C# 2, method groups are implicitly convertible to compatible delegate types. Visual Studio 2012 fixes this and generates the shorter form:

image

OK, this is a very small change, but the previous behavior was really annoying me… I had actually suggested this improvement on Connect, so I’m glad to see that it was implemented.

Improved Find/Replace

The Find dialog in Visual Studio had not seen any improvement for as long as I can remember (probably since VS2003 or VS2005), so it was time for a change… In VS2012, it has been replaced with the Quick Find feature from the Productivity Power Tools extension. It appears as a small panel in the top right corner of the text editor, much less obtrusive than the old dialog:

image

It provides the following features:

  • incremental search (matches are highlighted as you type in the search box)
  • quick access to options such as match case, match whole word, or regex through the search field dropdown
  • support for .NET regular expressions (the old Find dialog was using a different kind of regex, not fully compatible with the .NET regex syntax)

If for some reason you need the full Find dialog, it’s still there: there’s a menu item to access it in the search field dropdown.

Quick launch

Where’s that command again? In the Debug menu or the Project menu? I can’t remember, and I don’t know the keyboard shortcut…

Sounds familiar? For me it does… Visual Studio has so many features that sometimes it can be hard to find what you’re looking for. That’s why the new Quick Access feature is a very welcome addition; it appears as a search box in the top right corner of the IDE, and allows you to type what you want to do:

image

Again, this feature comes from the Productivity Power Tools extension, and has been included in Visual Studio itself. It has also been given a more prominent place in the IDE (in VS2010 it was only accessible through the Ctrl+Q shortcut).

Smarter Solution Explorer

The Solution Explorer used to show only the files in your project, but nothing about what was in the files; If you want to see the classes and members, you had to switch to the Class View. Visual Studio 2012 changes that: now you can see what is declared in a file, just by expanding the node in the Solution Explorer:

image

This feature had been in Eclipse for a long time, so it was time for Visual Studio to catch up Clignement d'œil.

A few other interesting features of the new Solution Explorer:

  • Scope to This: allows to re-root the tree to a specific node (e.g. if you want to see only the content of a folder). The re-rooted tree can be viewed in a separate view.
  • Pending Changes Filter: show only pending changes (if source control is active for the current project)
  • Open Files Filter: show only open files
  • Sync With Active Document: quickly locate the current document in the Solution Explorer (very useful for large solutions)

And yes, that’s yet another feature that comes from Productivity Power Tools (it was known as the Solution Navigator), with a few improvements.

ALL CAPS MENUS

Menus in VS2012 are in ALL CAPS, and it’s not exactly the most popular change… there has been tons of negative feedback about this! Frankly, I’m a bit surprised that people pay so much importance to such an insignificant detail, when there are so many more important things to discuss. Personally, I found it a bit unsettling when I saw the first screenshots, but when I got my hands on the RC I found that it didn’t bother me at all. I guess most people will just get used to it in the end…

Anyway, the reason I mention this is to say that if you really don’t like the ALL CAPS menus, you can get the normal casing back with a simple registry tweak. Just open regedit, go to the HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\General key, create a DWORD value named SuppressUppercaseConversion and set it to 1.

kick it on DotNetKicks.com

css.php