Web Api — как вернуть динамический объект с кодом состояния 201

Я пытаюсь вернуть недавно добавленный идентификатор объекта в метод действия веб-API в виде JSON. Пример:

{ bookId = 666 }

Код действия контроллера выглядит следующим образом:

[HttpPost, Route("")]
public HttpResponseMessage Add(dynamic inputs)
{
    int bookId = bookService.Add(userId, title);

    dynamic book = new ExpandoObject();
    book.bookId = bookId

    return new HttpResponseMessage(HttpStatusCode.Created)
    {
        Content = new ObjectContent<dynamic>(book,
            new JsonMediaTypeFormatter
            {
                UseDataContractJsonSerializer = true
            })
    };
}

Проблема здесь заключается в том, чтобы вернуть динамический контент (без Dto) и вернуть HttpStatusCode.Created (статус http 201).

Теперь у меня следующая ошибка:

{"Message":"Произошла ошибка.","ExceptionMessage":"Тип 'ObjectContent`1' не смог сериализовать тело ответа для типа содержимого 'application/json; charset=utf-8'.","ExceptionType ":"System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"Произошла ошибка.","ExceptionMessage":"Нет такого типа 'System.Dynamic.ExpandoObject' .. .

если я изменю new ObjectContent<dynamic> на new ObjectContent<ExpandoObject>, я получу правильный ответ заголовка состояния 201, но результат JSON будет следующим:

[{"Key":"bookId","Value":666}]

Итак, можно ли вернуть {bookId: 666} с помощью динамики (не Dtos), установив для кода состояния заголовка значение 201 (Создано)?

Спасибо за помощь.


person Xavier Egea    schedule 25.06.2014    source источник


Ответы (1)


Поведение, которое вы видите, является правильным, потому что dynamic / ExpandoObject фактически является просто оболочкой вокруг Dictionary<TKey, TValue>.

Если вы хотите, чтобы он был сериализован как объект, вам следует использовать анонимный объект вместо ExpandoObject например.

int bookId = bookService.Add(userId, title);

var book = new { bookId = bookId };

return new HttpResponseMessage(HttpStatusCode.Created)
{
    Content = new ObjectContent<object>(book,
        new JsonMediaTypeFormatter
        {
            UseDataContractJsonSerializer = true
        })
};

Если JsonMediaTypeFormatter не поддерживает анонимные объекты, вы можете попробовать использовать сериализатор по умолчанию.

return this.Request.CreateResponse(HttpStatusCode.OK, book);
person James    schedule 25.06.2014
comment
this.Request.CreateResponse(HttpStatusCode.OK, книга); работает как шарм. Благодарю вас! - person Xavier Egea; 25.06.2014