gpt4 book ai didi

asp.net - 仅返回 Web API 结果中选定的字段

转载 作者:行者123 更新时间:2023-12-02 15:23:20 25 4
gpt4 key购买 nike

我的模型包含的值比我的 Web API 消费者所需的多得多。

public class Publication
{
[Key]
public int PublicationID { get; set; }
public string PublicationTitle { get; set; }
public string Frequency { get; set; }
public DateTime NextIssueDate { get; set; }
public DateTime SpaceDeadline { get; set; }
public DateTime MaterialsDeadline { get; set; }
public DateTime CreatedDt { get; set; }
public string CreatedBy { get; set; }
public DateTime UpdatedDt { get; set; }
public string UpdatedBy { get; set; }
}

我只想说 API 中要传递的一些字段。我已经尝试过这段代码,但它没有在 JSON 结果中省略 UpdateBy,而是返回一个 null 值。我该如何摆脱它?

    public IQueryable<Publication> GetPublications()
{
return db.Publications
.ToList()
.Select(p => new Publication {
PublicationID = p.PublicationID,
PublicationTitle = p.PublicationTitle,
Frequency = p.Frequency,
NextIssueDate = p.NextIssueDate
})
.AsQueryable();
}

最佳答案

不要序列化您的 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; }
}

无需太多努力,您可能可以将其放入默认媒体类型格式化程序(在管道中)中,以在请求中查找名为“字段”或其他名称的参数,然后使用自定义契约(Contract)解析器(如果存在),然后它将无缝默认行为,以限制字段(如果指定)或序列化整个对象(如果未指定)。

从学术角度来看,理由如下:对数据的任何修改都被视为“ View 关注点”,这意味着在 API 中,它应该由查询参数和接受 header 控制。在本例中,数据的“表示形式”是 application/json,并且您选择“过滤”返回的字段。所有这些都可以(而且应该是)在序列化期间处理。因此,在这种情况下,您的“模型”将始终是完整模型与模型的某些子集。此示例中的完整模型包含名字、姓氏和年龄。实际上,这可能是数百个属性。如果您希望允许客户端选择完整模型的子集,则可以通过选择性序列化来实现此目的。

您可以在图形 API 中执行类似的行为。在那里,大型模型的默认设置是,如果不指定字段,您将得到一个空对象,从而迫使客户端非常具体地了解其要求的内容,这在有效负载大小很重要时(例如移动应用程序)非常有用。而且,没有什么可以阻止创建字段预设,例如“名称”,它可能意味着“名字、姓氏”或包含所有属性的“全部”。

我从来不喜欢拥有数百个数据对象,这些数据对象都满足在 20 个不同上下文中使用的数据集的某些临时要求,其中某些情况需要更多数据,而其他情况则需要更少。在我看来,如果您必须经历相同的过程来获取数据,无论是否完整,您都不应该浪费时间为了客户端而创建额外的对象来构建数据,这应该可以帮助您实现这一目标。

关于asp.net - 仅返回 Web API 结果中选定的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32019687/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com