.NET Client Library
Communicate with Couchbase Server using .NET
Note: Version 1.2 is the most recent release of this SDK. It is recommended for all deployments.
This Couchbase Client Library for .NET provides a complete interface to the functionality of Couchbase using the .NET framework. For more on Couchbase Server and .NET read our Getting Started guide followed by our in-depth Couchbase and .NET tutorial.
Getting Started
Here is a video that demonstrates how to use the Couchbase .NET Client Library:
Couchbase .NET Client on Vimeo.
Download and Installation
The easiest way to add the Couchbase .NET Client to your application is to use the Nuget package manager.
You can also download the latest release from the link at at the upper right of this page.
If you prefer to work with the source, you can find that on Github.
cd couchbase-net-client
git init submodule
git submodule update
Hello, Couchbase!
Project Setup
Create a new console project in Visual Studio. Either use Nuget to add the CouchbaseNetClient package or add a reference to the Couchbase.dll and Enyim.Memcached.dll assemblies.
Visual Studio console applications target the .NET Framework Client Profile by default, so you'll need to update the project properties to instead target the full .NET Framework. If you skip this step, you'll get compilation errors.
Adding Configuration
You can configure your Couchbase client either programmatically or using the app.config file with the appropriate Couchbase config section. Using app.config is more flexible and is the preferred approach. Modify your app.config file as follows:
<configuration>
<configSections>
<section name="couchbase" type="Couchbase.Configuration.CouchbaseClientSection, Couchbase"/>
</configSections>
<couchbase>
<servers bucket="default" bucketPassword="">
<add uri="http://192.168.0.2:8091/pools"/>
<add uri="http://192.168.0.3:8091/pools"/>
</servers>
</couchbase>
</configuration>
The URIs in the servers list are used by the client to obtain information about the cluster configuration. If you're running on your local dev machine, include only a single URI using 127.0.0.1 as the address.
The default Couchbase Server installation creates a bucket named default without a password. Modify this configuration section to match your particular setup.
Getting Started
Add the following using statements to Program.cs:
using Enyim.Caching.Memcached;
Couchbase is the namespace containing the client and configuration classes you'll work with. Enyim.Caching.Memcached contains supporting infrastructure. Couchbase protocol compatible with Memcached.
Next create an instance of the client in the Main method. Use the default constructor, which relies on the configuration from app.config.
To store data on the server, use the client's Store method.
To retrieve the data, use the Get method.
To retrieve the data without needing an explicit cast, use the generic form of Get.
Complex Types
You can persist your own classes in Couchbase. You need only mark your classes as Serializable.
public class Beer {
public Guid Id { get; set; }
public string Name { get; set; }
public string Brewery { get; set; }
}
Persist an instance of your type just as you would a primitive type.
var beer = new Beer {
Id = key,
Name = "Old Yankee Ale",
Brewery = "Cottrell Brewing Company"
};
client.Store(StoreMode.Add, "beer_" + key, beer);
And retrieve the Beer instance as you would a primitive type.
Storing JSON Documents
When Couchbase Server 2.0 is released, you'll no doubt want to take advantage of its powerful new View functionality. Working with views means storing your data as JSON documents. By the time Couchbase Server 2.0 is released, you should expect that the .NET Client will contain support for JSON transcoding either via explicit configuration or additional API calls. In the meantime, if you want to plan for 2.0 or simply work with JSON now, here is one approach.
CouchbaseClient Extension Methods
If you want an easy way to read and write JSON, you could add extension methods that serialize and deserialize your objects to and from JSON. This example uses the DataContractJsonSerializer found in the System.Runtime.Serialization assembly in .NET 4.0 (for 3.5, this class is found in the System.ServiceModel.Web assembly). You could just as easily implement these methods with another JSON serializer, such as the popular open source JSON.NET library.
Create a static class named CouchbaseClientExtensions:
...
}
To write JSON data, add the following method:
var ms = new MemoryStream();
var serializer = new DataContractJsonSerializer(typeof(T));
serializer.WriteObject(ms, value);
var json = Encoding.Default.GetString(ms.ToArray());
ms.Dispose();
return client.Store(storeMode, key, json);
}
To read JSON data:
var json = client.Get<string>(key);
var ms = new MemoryStream(Encoding.Default.GetBytes(json));
var serializer = new DataContractJsonSerializer(typeof(T));
var obj = serializer.ReadObject(ms) as T;
ms.Dispose();
return obj;
}
This method reads a string (JSON document) by using the CouchbaseClient's generic Get method. That string is then written to a MemoryStream, which is then used by the JSON serializer to hydrate an instance of T.
Using the JSON Extension Methods
The DataContractJsonSerializer will add metadata to the serialized JSON if you don't decorate your class with attributes from the System.Runtime.Serialization namespace. The new Beer class is below. The addition of the Type property is to give Beer documents a taxonomy. This convention will be useful when creating views with Couchbase Server 2.0.
public class Beer {
[DataMember(name="id")]
public Guid Id { get; set; }
[DataMember(name="name")]
public string Name { get; set; }
[DataMember(name="brewery")]
public string Brewery { get; set; }
[DataMember(name="type")]
public string Type { get; set; }
}
Persisting an instance as JSON is similar to how you persisted it above, except that the generic type is required.
var beer = new Beer {
Id = key,
Name = "American Ale",
Brewery = "Thomas Hooker Brewing Company",
Type = "beer"
};
client.StoreJson<Beer>(StoreMode.Add, "beer_" + key, beer);
And retrieving the Beer instance is also similar to retrieving as shown above.
Operation Results
There are three variants of CouchbaseClient API methods that return increasing levels of detail as to the success or failure of an operation. Depending on the level of information you require at runtime, you could choose from any of the approaches outlined below.
Single Value Results
If the success of an operation doesn't need to be determined at runtime (often the case with caching) you might find it sufficient to use the API methods that return single or scalar values.
bar = "bar";
var result = client.Store(StoreMode.Set, "foo", bar);
if (result) {
Console.WriteLine("Store operation was successful");
}
These API methods return either Booleans indicating the success of an operation (Store, Prepend, Append, Remove), ulong values (Increment, Decrement) or the item at a key (Get). Most exceptions will not bubble up to these methods and will require logging (see below) to get detailed information about failures.
CAS Results
For check and set operations, the return values are wrapped in a CasResult instance. The success of the operation is still determined by a Boolean and detailed failures still require logging.
var bar = "bar";
var result = client.Cas(StoreMode.Set, "foo", bar, result.Cas);
if (result.Result) {
Console.WriteLine("CAS operation was successful");
}
These CasResult API methods return the Result property as a Boolean (Cas, Prepend, Append), as ulong (Increment, Decrement) or the item at a key or an object (Get). As with the single value results, most exceptions will not bubble up to these methods and will require logging (see below) to get detailed information about failures.
Detailed Operation Results
When you need to react at runtime to detailed information about an operation, you can use the IOperationResult API methods. These methods all return instances of a class that implements and possibly extends IOperationResult. The table below summarizes these interface properties.
Each of these methods shares its name with a method from the single-value return API, but prefixed with "Execute." For example, Get() becomes ExecuteGet() and Store() becomes ExecuteStore().
| Property | Interface | Description |
| Success | IOperationResult | Whether the operation succeeded |
| Message | IOperationResult | Error, warning or informational message |
| StatusCode | IOperationResult | Nullable status code from server |
| InnerResult | IOperationResult | Nested result. Populated by low-level I/O failures. |
| Value | INullableOperationResult | Extended by IGetOperationResult, where Value is item for given key. |
| HasValue | INullableOperationResult | Shortcut for null Value check. |
| Cas | ICasOperationResult |
Extended by IGetOperationResult, IMutateOperationResult, IConcatOperationResult and IStoreOperationResult. Contains possible CAS value for operations. |
if (getResult.Success && getResult.HasValue) {
var beer = getResult.Value;
beer.Brewery = "The Alchemist";
var casResult = client.ExecuteCas(StoreMode.Set, "beer_heady_topper", beer, getResult.Cas);
if (casResult.Success) {
Console.WriteLine("CAS operation was successful");
}
} else {
Console.WriteLine("Get operation failed with message {0} and exception {1} ",
getResult.Message, getResult.Exception);
}
It's a good idea with the IOperationResult API to check the InnerResult or StatusCode properties on failures. When socket I/O failures occur, the client library will gracefully handle them. Therefore, errors are wrapped up and passed through the layers. Generally, these errors are bubbled up via the InnerResult properties.
Configuring Logging
To enable logging, you can tap into the logging capabilities provided by the Enyim.Caching dependency. Enyim logging currently supports either log4net or NLog.
Start by adding a reference to either Enyim.Caching.Log4NetAdapter or Enyim.Caching.NLogAdapter. Both are available as nuget packages.
http://nuget.org/packages/EnyimMemcached-log4net
http://nuget.org/packages/EnyimMemcached-nlog
You could also get the projects from https://github.com/enyim/EnyimMemcached. If you use these Visual Studio projects, you'll also need to add a reference to log4net or NLog (depending on which adapter you choose). Each of these dependencies is located in a "binaries" directory under the root "EnyimMemcached" directory.
For log4net, your configuration should include an enyim.com section that defines which log factory to use along with standard log4net configuration.
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="log" type="Enyim.Caching.Configuration.LoggerSection, Enyim.Caching" />
</sectionGroup>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<enyim.com>
<log factory="Enyim.Caching.Log4NetFactory, Enyim.Caching.Log4NetAdapter" />
</enyim.com>
<log4net debug="false">
<appender name="LogFileAppender" type="log4net.Appender.FileAppender,log4net">
<param name="File" value="c:\\temp\\error-log.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%X{auth}> - %m%n" />
</layout>
</appender>
<root>
<priority value="ALL" />
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
The log4net configuration will vary by the type of appender you are using. For more information on log4net configuration, see http://logging.apache.org/log4net/release/manual/configuration.html.
You'll also need to initialize (only once in your app) log4net in your code with the standard log4net initializer.
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="log" type="Enyim.Caching.Configuration.LoggerSection, Enyim.Caching" />
</sectionGroup>
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
</configSections>
<enyim.com>
<log factory="Enyim.Caching.NLogFactory, Enyim.Caching.NLogAdapter" />
</enyim.com>
<nlog>
<targets>
<target name="logfile" type="File" fileName="c:\temp\error-log.txt" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
</configuration>