I usually don’t blog about when I do a new release of MyCouch – THE async .Net driver for CouchDB and Cloudant; so why this time? Well, because it’s a rather embarrassing little fix, in the sense:
Why did I not support this earlier?
Yeah, why didn’t I? Let me try and explain why but first, lets look at what the fix actually solves.
I got a report stating that the driver could not handle CouchDB _id
s with chars in the need of encoding, e.g. "persons/1"
using (var client = new MyCouchClient("http://localhost:5984/foo"))
{
var db = await client.Database.PutAsync();
var put = await client.Entities.PutAsync(
new Person { Id = "persons/1", Name = "Daniel" });
var get = await client.Entities.GetAsync(put.Id);
}
With the release of v2.4.2
of MyCouch, this is now possible. Please note though, that (as I see it) Microsoft has a flaw in their HttpClient
distributed via NuGet, for getting HttpClient
in .Net4.0, so to support this in .Net4.0, you have to do an ugly workaround as documented here: Support for _id in the need of encoding
Why was this not supported before?
Easy, no one has needed it. Why? Well, I do know that some storage solutions uses the Id
to indicate “type of entity” or “collection”. If you look at the end-point it makes a bit sense perhaps, that you have the database/collection/id
. How-ever, CouchDB, does not have any built in support for having “types of documents”. All documents are siblings and stored in the same database. Usually, you deal with this in your maps
(as in map & reduce) by adding an attribute to your documents, indicating what kind of document it is. This has been supported from the beginning in MyCouch as it automatically injects a$doctype
property that you can use for this. You can also override the $doctype
either by hooking in a custom convention or by using attributes.
How-to override $doctype and provide more meta-data using attributes
You can override the $doctype
and-also provide other meta-data, like a namespace or a version of the document by the use of an attribute.
[Document(
DocType = "MyType",
DocNamespace = "MyNamespace",
DocVersion = "1.2.1")]
public class ModelEntityWithMeta
{
public string Id { get; set; }
public string Rev { get; set; }
public string Value { get; set; }
}
How-to override $doctype and provide more meta-data using a serialization configuration
When you construct e.g. your MyCouchClient
you can pass in a custom MyCouchClientBootstrapper
. Inside of it, there’s a member SerializationConfigurationFn
that determines the configurations to use for the serialization. On that, there’s a member Conventions
, that has some ISerializationConvention
you can assign your own conventions to. The default implementation looks like this:
public class SerializationConventions
{
public ISerializationConvention DocType { get; set; }
public ISerializationConvention DocNamespace { get; set; }
public ISerializationConvention DocVersion { get; set; }
public virtual bool HasConventions
{
get { return ...; }
}
public SerializationConventions()
{
DocType = new StringSerializationConvention(
"$doctype",
m => !m.IsAnonymous ? m.DocType.ToCamelCase() : null);
DocNamespace = new StringSerializationConvention(
"$docns",
m => m.DocNamespace);
DocVersion = new StringSerializationConvention(
"$docver",
m => m.DocVersion);
}
}
That’s all for now. Hope you find MyCouch useful.
Cheers,
//Daniel