Чтение контента CollectionJson в проекте Web Api

У меня есть проект, похожий (почти идентичный) на проект Conference API, который использует похожий подход к упомянутому проекту для возврата содержимого CollectionJson. У меня возникают трудности при настройке свойства Collection в ReadDocument (строка 30), так как у него нет никакого установщика. Я мог бы обойти эту проблему, сделав следующее изменение

public CollectionJsonContent(Collection collection)
{
    var serializerSettings = new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            Formatting = Newtonsoft.Json.Formatting.Indented,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    collection.Version = "1.0";

    Headers.ContentType = new MediaTypeHeaderValue("application/vnd.collection+json");

    using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false})
    {
        //var readDocument = new ReadDocument(); {IReadDocument.Collection = collection};
        var serializer = JsonSerializer.Create(serializerSettings);
        serializer.Serialize(writer,collection);
        writer.Flush();
    }
    _memoryStream.Position = 0;
}

Хотя приведенный выше код компилируется и в некоторой степени решает проблему, но с другой стороны, у меня возникнет еще одна проблема, заключающаяся в том, что я не могу использовать содержимое JsonCollection в тестах моего контроллера. Рассмотрим следующий фрагмент кода модульного теста:

            using (var request = CreateRequest())
            {                
                var controller = new TestController(DataService) {Request = request};

                var temp = await controller.ListAsync(gridSearchData, sampleSearchData);

                if ((temp is NotFoundResult) && (sampleCollection.Any()))
                {
                    Assert.Fail("Controller did not return any result but query did");
                }

                var json = await temp.ExecuteAsync(cancellationTokenSource);



                var readDocument = json.Content.ReadAsAsync<ReadDocument>(new[] {new CollectionJsonFormatter()}, cancellationTokenSource).Result;

         }

Так как я не установил свойство коллекции ReadDocument, readDocument всегда пуст, и я не могу прочитать его содержимое. Как вы асинхронно читаете содержимое JsonCollection на стороне клиента в проектах WEB API?

Чтобы получить четкое представление о подходе, загляните в Conference Web Api и блог авторов.

3 ответа

Решение

OK все, это было исправлено. Свойство Collection теперь снова устанавливается.

Я только что выпустил релиз 0.7.0 с этим исправлением, основным рефакторингом именования, а также хорошим улучшением сериализации, чтобы не выписывать пустые коллекции.

Пожалуйста, ознакомьтесь с примечаниями к выпуску для внесения изменений (особенно наименования, так как имена пакетов и пространства имен изменились)

Я смотрю на это и придумаю решение с надеждой на эти выходные, которое будет либо сделать его общедоступным установщиком, либо сделать его внутренним и иметь публичный ctor, который принимает коллекцию.

Извините за сложность.

Насколько я вижу из вашего кода, вы не сериализуете ReadDocument объект, но только его свойство (Collection), а затем вы пытаетесь десериализовать это значение в новый ReadDocument объект.

Образец ReadDocument следует сериализовать так

"{"Collection": [1,2,3,4,5] }"

Но вы сериализуете коллекцию, так что вы получаете

"[1,2,3,4,5]"

Я рекомендую суррогатный класс для сериализации, как это

class SerializableReadDocument
{
   public Collection Collection { get; set; }
}

и обновите свой код сериализации, как это

using (var writer = new JsonTextWriter(new StreamWriter(_memoryStream)){CloseOutput = false})
{
    var readDocument = new SerializableReadDocument() { Collection = collection };
    var serializer = JsonSerializer.Create(serializerSettings);
    serializer.Serialize(writer, readDocument);
    writer.Flush();
}

Но это не решит вашу проблему, когда вы попытаетесь десериализовать свой вывод, так как ReadDocument не имеет настраиваемого значения Collection свойство, десериализация либо потерпит неудачу, либо вернет ReadDocument объект с пустым Collection,

Ты можешь использовать SerializableReadDocument если вам нравится в ваших модульных тестах.

Другие вопросы по тегам