【发布时间】:2018-10-28 14:06:14
【问题描述】:
我想创建自定义 JSON 格式,它将响应包装在数据中并返回 Content-Type
vnd.myapi+json
目前我已经创建了一个包装类,我在我的控制器中返回,但如果可以在后台处理它会更好:
public class ApiResult<TValue>
{
[JsonProperty("data")]
public TValue Value { get; set; }
[JsonExtensionData]
public Dictionary<string, object> Metadata { get; } = new Dictionary<string, object>();
public ApiResult(TValue value)
{
Value = value;
}
}
[HttpGet("{id}")]
public async Task<ActionResult<ApiResult<Bike>>> GetByIdAsync(int id)
{
var bike = _dbContext.Bikes.AsNoTracking().SingleOrDefault(e => e.Id == id);
if (bike == null)
{
return NotFound();
}
return new ApiResult(bike);
}
public static class ApiResultExtensions
{
public static ApiResult<T> AddMetadata<T>(this ApiResult<T> result, string key, object value)
{
result.Metadata[key] = value;
return result;
}
}
我想返回如下响应:
{
"data": { ... },
"pagination": { ... },
"someothermetadata": { ... }
}
但是必须以某种方式将分页添加到我的控制器操作中的元数据中,当然这里有一些关于内容协商的文章:https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-2.1 但我仍然想确保我走在正确的轨道上。
如果这将使用我的自定义格式化程序在后台处理,那么我将如何向它添加像分页这样的元数据,将其放在“数据”之外而不是其中?
当有一个自定义格式化程序时,我仍然希望有一些方法可以从我的控制器或通过某种机制向它添加元数据,以便格式可以扩展。
上述方法的一个优点或缺点是它适用于所有序列化程序 xml、json、yaml 等。通过使用自定义格式化程序,它可能仅适用于 json,我需要创建几个不同的格式化程序来支持所有我想要的格式。
【问题讨论】:
-
我不确定您是否要说是否需要自定义数据格式,即不是 JSON,而是接近 JSON 的格式(在这种情况下为什么)。或者您担心数据本身的结构(这只是您序列化的模型)。或者,如果您担心 JSON 的格式 - 即换行符/制表符等(如果是这样,为什么)?
-
@JamesGaunt 我仍然想要 JSON,但我想将我的结果包装在“数据”中,这样我就可以在它旁边添加一些元数据,例如分页。这对于实现 HATEOAS 也很有用,我想在其中添加一些指向我的数据的链接以及可能的操作。例如jsonapi.org
-
在这种情况下,我认为您的方法是正确的。这并不是真正的 mime 类型更改 - 它只是您的 API 的设计方式。因此,您需要向 JSON 序列化程序发送一个适当的模型——这正是您正在做的事情。您希望通过“隐藏”来获得什么?
-
如果它只是您想要更改的 MIME 类型,您可以通过自己序列化 JSON 并返回具有您想要的任何 MIME 类型的内容结果来做到这一点。
-
如果您只是不希望控制器中的代码(它显而易见且清晰) - 并且宁愿将其隐藏在某个地方 - 也许是一个 ResultFilter。不知道这是否是个好主意! docs.microsoft.com/en-us/aspnet/core/mvc/controllers/…
标签: c# asp.net-core asp.net-core-mvc asp.net-core-webapi