web.api только сериализует скрытые поля
Я испытываю странное поведение. Мой web.api возвращает только скрытые поля из моей коллекции объектов по запросу GET. Это мой контроллер:
// GET: api/UserDocuments
[Route("api/UserDocuments/User/{userName}")]
public List<DocIndex> Get(string userName)
{
User usuari = Humanisme.User.LoadByUserName(userName);
List<DocIndex> resposta = DocumentCollection.LoadIndexPerUsuari(usuari);
return resposta;
}
И это объект, поскольку он генерируется из спецификации:
namespace Humanisme
{
using CodeFluent.Runtime;
using CodeFluent.Runtime.Utilities;
// CodeFluent Entities generated (http://www.softfluent.com). Date: Tuesday, 01 March 2016 11:52.
// Build:1.0.61214.0820
[System.CodeDom.Compiler.GeneratedCodeAttribute("CodeFluent Entities", "1.0.61214.0820")]
[System.SerializableAttribute()]
[System.ComponentModel.DataObjectAttribute()]
public partial class DocIndex : CodeFluent.Runtime.ICodeFluentLightEntity
{
private int _id = -1;
[System.NonSerializedAttribute()]
private Humanisme.User _user = ((Humanisme.User)(null));
private string _lat = default(string);
private string _lon = default(string);
private string _etapaVital = default(string);
private string _solvencia = default(string);
private int _valoracio = CodeFluentPersistence.DefaultInt32Value;
private System.DateTime _data = CodeFluentPersistence.DefaultDateTimeValue;
private string _nom = default(string);
public DocIndex()
{
}
[System.ComponentModel.DefaultValueAttribute(((int)(-1)))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(int))]
[System.ComponentModel.DataObjectFieldAttribute(true)]
public int Id
{
get
{
return this._id;
}
set
{
this._id = value;
}
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public Humanisme.User User
{
get
{
return this._user;
}
set
{
this._user = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Lat
{
get
{
return this._lat;
}
set
{
this._lat = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Lon
{
get
{
return this._lon;
}
set
{
this._lon = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string EtapaVital
{
get
{
return this._etapaVital;
}
set
{
this._etapaVital = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Solvencia
{
get
{
return this._solvencia;
}
set
{
this._solvencia = value;
}
}
[System.ComponentModel.DefaultValueAttribute(CodeFluentPersistence.DefaultInt32Value)]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(int))]
public int Valoracio
{
get
{
return this._valoracio;
}
set
{
this._valoracio = value;
}
}
[System.Xml.Serialization.XmlElementAttribute(IsNullable=false, Type=typeof(System.DateTime))]
public System.DateTime Data
{
get
{
return this._data;
}
set
{
this._data = value;
}
}
[System.ComponentModel.DefaultValueAttribute(default(string))]
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Type=typeof(string))]
public string Nom
{
get
{
return this._nom;
}
set
{
this._nom = value;
}
}
protected virtual void ReadRecord(System.Data.IDataReader reader, CodeFluent.Runtime.CodeFluentReloadOptions options)
{
if ((reader == null))
{
throw new System.ArgumentNullException("reader");
}
if ((((options & CodeFluent.Runtime.CodeFluentReloadOptions.Properties)
== 0)
== false))
{
this._id = CodeFluentPersistence.GetReaderValue(reader, "Id", ((int)(-1)));
this._user = new Humanisme.User();
CodeFluent.Runtime.CodeFluentLightWeightPersistence.ReadRecord(reader, this._user, null, new CodeFluent.Runtime.Utilities.Pair<string, string>("Id", "User_Id"));
this._lat = CodeFluentPersistence.GetReaderValue(reader, "Lat", ((string)(default(string))));
this._lon = CodeFluentPersistence.GetReaderValue(reader, "Lon", ((string)(default(string))));
this._etapaVital = CodeFluentPersistence.GetReaderValue(reader, "EtapaVital", ((string)(default(string))));
this._solvencia = CodeFluentPersistence.GetReaderValue(reader, "Solvencia", ((string)(default(string))));
this._valoracio = CodeFluentPersistence.GetReaderValue(reader, "Valoracio", ((int)(CodeFluentPersistence.DefaultInt32Value)));
this._data = CodeFluentPersistence.GetReaderValue(reader, "Data", ((System.DateTime)(CodeFluentPersistence.DefaultDateTimeValue)));
this._nom = CodeFluentPersistence.GetReaderValue(reader, "Nom", ((string)(default(string))));
}
}
void CodeFluent.Runtime.ICodeFluentLightEntity.ReadRecord(System.Data.IDataReader reader)
{
this.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
}
}
}
Вызов метода get web.api возвращает этот JSON:
[
{
"_id": 1,
"_lat": null,
"_lon": null,
"_etapaVital": null,
"_solvencia": null,
"_valoracio": 0,
"_data": "0001-01-01T00:00:00",
"_nom": null
}
]
Сериализатор (из WebApiConfig.cs)
JsonMediaTypeFormatter jsonFormatter = (JsonMediaTypeFormatter)config.Formatters.FirstOrDefault(f => f is JsonMediaTypeFormatter);
if (jsonFormatter != null)
{
// jsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Include;
jsonFormatter.UseDataContractJsonSerializer = true;
}
2 ответа
Наконец-то нашел!
При работе с web.api никогда, никогда не забывайте добавлять в ваш модельный проект подпроизводитель "Service Producer", присоединенный к стандартному BOM Producer.
Вы никогда не заметите никаких проблем, но при сериализации, когда никакие атрибуты не будут обработаны и только выходные свойства (поля объекта) будут сериализованы при выводе.
Извините за ошибку, рад за урок.
Еще раз спасибо Мезианту. Вы бы никогда не поняли, откуда возникла проблема, в основном потому, что я не отнес все детали проекта к вопросу.
Классы, созданные CodeFluent Entities, оформлены SerializableAttribute
, Этот атрибут меняет способ Json.NET
сериализовать или десериализовать объект. Вы можете настроить Json.NET
игнорировать этот атрибут:
JsonMediaTypeFormatter jsonFormatter = (JsonMediaTypeFormatter)config.Formatters.FirstOrDefault(f => f is JsonMediaTypeFormatter);
if (jsonFormatter != null)
{
jsonFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
};
}
Теперь Json.NET обнаруживает типы, имеющие атрибут SerializableAttribute, и сериализует все поля этого типа, как публичные, так и частные, и игнорирует свойства
Таким образом, вы можете использовать сервис-производителя, который добавит DataMemberAttribute
или вы можете использовать Json.NET Aspect
для автоматического добавления определенного атрибута Json.NET: Newtonsoft.Json.JsonObjectAttribute
а также Newtonsoft.Json.JsonPropertyAttribute
,