Дон» t сериализуйте свой DAO. Создайте полный контракт и затем сериализуйте его выборочно. Для создания разных контрактов для разных случаев вы можете упростить его с помощью Json.Net; вы можете просто создать собственный контракт распознаватель и использовать его в качестве параметра SerializeObject() как так
static void Main(string[] args)
{
var person = new TestContract {FirstName = "John", LastName = "Doe", Age = 36};
var firstNameContract = new SelectiveSerializer("firstname");
var allPropertiesContract = new SelectiveSerializer("firstname, lastname, age");
var allJson = JsonConvert.SerializeObject(
person,
Formatting.Indented,
new JsonSerializerSettings {ContractResolver = allPropertiesContract});
var firstNameJson = JsonConvert.SerializeObject(
person,
Formatting.Indented,
new JsonSerializerSettings {ContractResolver = firstNameContract});
Console.WriteLine(allJson);
// {
// "FirstName": "John",
// "LastName": "Doe",
// "Age": 36
// }
Console.WriteLine(firstNameJson);
// {
// "FirstName": "John",
// }
}
public class SelectiveSerializer : DefaultContractResolver
{
private readonly string[] _fields;
public SelectiveSerializer(string fields)
{
var fieldColl = fields.Split(',');
_fields = fieldColl
.Select(f => f.ToLower().Trim())
.ToArray();
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
property.ShouldSerialize = o => _fields.Contains(member.Name.ToLower());
return property;
}
}
public class TestContract
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
без особых усилий, вы могли бы, вероятно, работать это в свой MEDIATYPE по умолчанию форматера (в трубопроводе) искать параметр в запросе, называемый «поля» или что-то еще, а затем использовать пользовательский разрешитель контрактов, если он присутствует, и тогда было бы плавное поведение по умолчанию для ограничения полей, если это указано или сериализует весь объект, если он не указан.
С учётной стороны, это обоснование: Любая модификация данных считается «озабоченностью по просмотру», что означает, что в API она должна контролироваться параметрами запроса и принимать заголовок. В этом случае «представление» данных - application/json, и вы решили «фильтровать» возвращаемые поля. Все это может (и должно быть, imo) обрабатываться во время сериализации. Таким образом, ваша «модель» в этом случае всегда будет полной моделью против некоторого подмножества модели. Полная модель в этом примере содержит имя, фамилию и возраст. На самом деле это могут быть сотни свойств. Если вы хотите разрешить клиенту выбирать подмножество полной модели, вы можете сделать это с помощью выборочной сериализации.
Аналогичные поведении можно выполнять в графике apis. Там по умолчанию для больших моделей является то, что вы получаете пустой объект, если не указываете поля, заставляя клиента быть очень конкретным в отношении того, что он запрашивает, что отлично, когда размер полезной нагрузки имеет значение (например, мобильные приложения). И нет ничего, что могло бы остановить создание полей, таких как «имя», которое могло бы означать «имя, фамилия» или «все», которое включает все свойства.
Я никогда не был поклонником наличия сотен объектов данных, которые обслуживают некоторые специальные требования к набору данных, который используется в 20 различных контекстах, где в некоторых случаях требуется больше данных, а в других - меньше. IMO, если вам нужно пройти один и тот же процесс, чтобы получить данные, независимо от того, завершено это или нет, вы не должны тратить свое время на создание дополнительных объектов для кадрирования данных ради клиента, и это должно помочь вам в этом.
Да, это то, что мне нужно сделать, создать модель представления. –
Преобразование запрашиваемого в перечислимое (через ToList()), а затем обратно к запросу не имеет смысла. Опустите теги .ToList() и .AsQueryable(), и ваш результат сопоставлен с вашим новым классом непосредственно из db. –