public TypeConventionBuilder<T> IncludeField<TProperty>(Expression<Func<T, TProperty>> fieldSelector, Action<T, TProperty> setter)
    string fieldName = base.ClientConventions.FieldNameConvention.GetFieldName(fieldSelector);
    Func<T, TProperty> getter = fieldSelector.Compile();
    JsonProperty jsonProperty = new JsonProperty {
        PropertyName = fieldName,
        ShouldSerialize = x => true,
        Readable = true,
        Writable = setter.IsNotNull(),
        PropertyType = typeof(TProperty)
    base.ModifyContract(delegate (JsonObjectContract contract) {
        if (!contract.Properties.Any<JsonProperty>(x => (x.PropertyName == base.jsonProperty.PropertyName)))
            this.jsonProperty.ValueProvider = new DelegateValueProvider<T, TProperty>(this.getter, this.setter);
    return (TypeConventionBuilder<T>) this;

In case you do include readonly field (setter == null)

conventions.ForType<TDocument>().IncludeField(x => SuggestionsSource(x));

it is better to specify property ObjectCreationHandling value:

   ObjectCreationHandling = ObjectCreationHandling.Replace

otherwise during deserialization even if property marked as "readonly" (Writable == false) it's ValueProvider.GetValue() is triggered and the result is passed to property converter ReadJson method as existingValue and deserialization occurs. But final value is not used anywhere (field has not setter defined).

I see follwing issues here:

1. Useless extra call during deserialization. Perfmonace: image that my field getter makes a heavy calls to DB

2. Extra coding. If I have custom json converter for my field type I have to implement ReadJson method, but what for (field is readonly and should be never deserialized back)? 

May 26, 2014 22:12
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.