Невозможно настроить сериализатор с помощью RavenDB и JsonConverter — возможная несовместимость с Json.Net 4.0.8

Для моего проекта я должен десериализовать строку Uri и следую предложению, предложенному в этом SO question путем создания собственного конвертера.

Когда я добавляю преобразование в сериализатор, представленный в RavenDB, я получаю следующую ошибку:

TestSuite.EmailSMSTests.CanSendSMSWithFilter: System.ArrayTypeMismatchException : Попытка доступа к элементу как типу, несовместимому с массивом.

Я добавляю преобразователь таким образом:

docStore.Conventions.CustomizeJsonSerializer = serializer => serializer.Converters.Add(new UriJsonConverter());
docStore.Initialize();

Я могу успешно добавить преобразователь, если создам JsonSerializer с Json.Net:

var serializer = new JsonSerializer();
serializer.Converters.Add(new UriJsonConverter());

Я подозреваю, что это может быть связано с перенаправлением сборки, так как мне нужна более поздняя версия Json.Net, которая работает с RESTSharp. В проекте используется Raven.client 960, Json.Net 4.08 и Json.Net 4.5.7. Любое понимание приветствуется.

Это код конвертера:

public class UriJsonConverter : JsonConverter
    {

        public override bool CanConvert(Type objectType)
        {
            return object.Equals(objectType, typeof(Uri));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            switch (reader.TokenType)
            {
                case JsonToken.String:
                    return CreateUri((string)reader.Value);
                case JsonToken.Null:
                    return null;
                default:
                    var msg = string.Format("Unable to deserialize Uri from token type {0}", reader.TokenType);
                    throw new InvalidOperationException(msg);
            }
        }

        private static Uri CreateUri(string uriString)
        {
            Uri uri;
            if (!Uri.TryCreate(uriString, UriKind.Absolute, out uri))
                if (!Uri.TryCreate(uriString, UriKind.Absolute, out uri))
                    if (!Uri.TryCreate(uriString, UriKind.RelativeOrAbsolute, out uri))
                    {
                        var msg = string.Format("Unable to determine proper UriKind for Uri {0}", uriString);
                        throw new InvalidOperationException(msg);
                    }
            return uri;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (null == value)
            {
                writer.WriteNull();
                return;
            }

            var uri = value as Uri;
            if (uri != null)
            {
                writer.WriteValue(uri.OriginalString);
                return;
            }
            var msg = string.Format("Unable to serialize {0} with {1}", value.GetType(), typeof(UriJsonConverter));
            throw new InvalidOperationException(msg);
        }

    }

person David Robbins    schedule 10.10.2012    source источник


Ответы (2)


Вы пробовали клиент Raven 972, использующий json 4.5.7? https://nuget.org/packages/RavenDB.Client/1.0.972

person Matt Johnson-Pint    schedule 11.10.2012
comment
да. Но поскольку я также использую пакет авторизации, я должен остаться с 960. - person David Robbins; 12.10.2012

Raven DB по какой-то странной причине включает в свой клиент старую версию Newtonsoft JSON. Чтобы зарегистрировать преобразователь типов, вам нужно сделать что-то вроде этого:

using (var store = new DocumentStore { Url = "http://..." })
{
    store.Initialize();

    // Required if you are going to serialize Identity types
    store.Conventions.IdentityTypeConvertors.Add(new IdentityTypeConverter());

    // This is how you register 
    store.Conventions.CustomizeJsonSerializer = serializer => serializer.Converters.Add(new IdentityTypeConverter());

...
}
person Nate Zaugg    schedule 22.04.2016