2014-11-13 1 views
0

У меня есть следующее действие веб-API.Web Api - Тип объекта ObjectContent не удалось сериализовать

public IHttpActionResult Get() { 
    var units = Enum.GetValues(typeof(UnitType)).Cast<UnitType>().Select(x => new { Id = (Int32)x, Description = x.Attribute<DescriptionAttribute>().Description }); 
    return Ok(units); 
} 

В принципе, я возвращаю значения и описания перечисления.

Я проверил список единиц и получил правильные значения.

Однако, когда я называю API я получаю следующее сообщение об ошибке:

<Error><Message>An error has occurred.</Message> 
<ExceptionMessage>The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.</ExceptionMessage> 
<ExceptionType>System.InvalidOperationException</ExceptionType> 
<StackTrace/><InnerException><Message>An error has occurred.</Message> 
<ExceptionMessage>Type '<>f__AnonymousType0`2[System.Int32,System.String]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.</ExceptionMessage> 

Почему?

UPDATE

теперь у меня есть:

public IHttpActionResult Get() { 
    IList<EnumModel> units = Enum.GetValues(typeof(UnitType)).Cast<UnitType>().Select(x => new EnumModel((Int32)x, x.Attribute<DescriptionAttribute>().Description)).ToList(); 
    return Ok(units); 
    } // Get 

public class EnumModel { 
    public Int32 Id { get; set; } 
    public String Description { get; set; } 

    public EnumModel(Int32 id, String description) { 
    Id = id; 
    Description = description; 
    } // EnumModel 
} // EnumModel 

Я получаю ошибку:

<Error> 
    <Message>An error has occurred.</Message> 
    <ExceptionMessage>The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.</ExceptionMessage> 
    <ExceptionType>System.InvalidOperationException</ExceptionType> 
    <StackTrace/><InnerException> 
    <Message>An error has occurred.</Message> 
    <ExceptionMessage>Type 'Helpers.EnumModel' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.</ExceptionMessage> 
    <ExceptionType>System.Runtime.Serialization.InvalidDataContractException</ExceptionType> 

Любая идея, почему?

ответ

0

Возможно, я ошибаюсь, но InnerException, кажется, предполагает, что анонимные типы не могут быть сериализованы.

Попробуйте объявить класс, такие как

public class EnumInfo { 
    public int Id { get; set; } 
    public string Description { get; set; } 

    public EnumInfo(int id, string description) { 
     Id = id; 
     Description = description; 
    } 
} 

и поворачивая Select вызов в

[...].Select(x => new EnumInfo((Int32)x, x.Attribute<DescriptionAttribute>().Description); 
+0

Я попытался с класс, как вы предложили, но я продолжаю иметь ту же ошибку ... –

+0

@MDMoura Вы могли бы отредактировать свой вопрос, указав ошибку, которую вы получаете * сейчас *? –

+0

Я только что обновил свой вопрос ... Мой класс кажется вполне нормальным, поэтому я не уверен, почему я получаю эту ошибку сейчас. –

2

Как вы звоните свой API? Похоже, он пытается использовать XML-форматтер для согласования контента. Однако XML-сериализатор не поддерживает анонимные типы. За подробной информацией обращайтесь к this link.

Чтобы устранить эту проблему, вы должны либо отправить Accept: application/json заголовок (если вы используете Скрипач или инструмент, как это), или явно указать свой Web API, что вам нужно только JSON форматировщик:

config.Formatters.Clear(); 
var jsonFormatter = new JsonMediaTypeFormatter 
{ 
    // Use camel case formatting. 
    SerializerSettings = 
    { 
     ContractResolver = new CamelCasePropertyNamesContractResolver(), 
    } 
}; 
config.Formatters.Add(jsonFormatter); 
+0

На самом деле я звоню в API в браузере, чтобы проверить его ... Так что это нормально, чтобы получить XML. Я изменяю анонимный тип на список , как это было предложено, но у меня такая же ошибка. Любая идея почему? –

+0

Не должен ли вызывающий абонент решать, какой тип хочет и не заставляет тип (JSON, XML, ...) в действии? –

+0

@MDMoura определенно, это основная идея согласования контента; однако в большинстве случаев требуется только формат JSON. –

Смежные вопросы