Your first request
To communicate with the Contentful API we will be using the ContentfulClient
class. The ContentfulClient
requires a few things to be up and running.
- An
HttpClient
. This will be used internally for making the http requests to the Contentful API. - An access token. You can create access tokens in the APIs tab of each space in the Contentful web app.
- A space id. This is the unique identifier of your space and can also be found in the Contentful web app.
var httpClient = new HttpClient();
// In our example we provide the access token 0b7f6x59a0 and the space id developer_bookshelf
var client = new ContentfulClient(httpClient, "0b7f6x59a0", "developer_bookshelf")
Why on earth do I need to supply my own HttpClient?
The HttpClient
in .Net is special. It implements IDisposable
but is generally not supposed to be disposed for the lifetime of your application.
The reason for this is that whenever you make a request with the HttpClient
and then immediately dispose it you leave the connection open
in a TIME_WAIT
state. It will remain in this state for 240 seconds by default. This means that if you have a lot of request in a short period of time you might
end up exhausting the connection pool. This would result in a SocketException
stating that
"Only one usage of each socket address (protocol/network address/port) is normally permitted.". To avoid this you should share a single instance of
HttpClient
for the entire application. Exposing the underlying HttpClient
of the ContentfulClient
allows you to do this.
Once we have an ContentfulClient
we can start querying content. Lets get a single entry for example:
var entry = await client.GetEntryAsync<Entry<dynamic>>("2CfTFQGwogugS6QcOuwO6q");
Console.WriteLine(entry.Fields.author.ToString()); // => Contentful
The GetEntry
method is generic and we can actually pass it any POCO class we so desire. It would then deserialize the JSON response from the API into that class for us. In our example
above we passed it an Entry
class as a generic type parameter. This has the additional benefit of allowing us the also retrieve the system meta data of the entry. In many cases we might
not be interested in the meta data and we can then pass any other class of our choice.
public class Book {
public string Name { get; set; }
public string Author { get; set; }
public string Description { get; set; }
}
If we pass this class to the GetEntry
method we will get our response as a strongly typed Book
.
var book = await client.GetEntryAsync<Book>("2CfTFQGwogugS6QcOuwO6q");
Console.WriteLine(book.Name); // => How to manage content in a developer-friendly manner
Console.WriteLine(book.Author); // => Contentful
Console.WriteLine(book.Description); // => Make an API request, get JSON in return.
Notice that the Entry
class is also generic, this means we can even combine the two approaches if we are interested in the system meta-data properties but also want to take advantage
of the strong typing.
var bookEntry = await client.GetEntryAsync<Entry<Book>>("2CfTFQGwogugS6QcOuwO6q");
Console.WriteLine(entry.Fields.Author); // => Contentful
Console.WriteLine(entry.SystemProperties.Id); // => 2CfTFQGwogugS6QcOuwO6q