- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我将 Odata 添加到我的项目中,这样我就可以使用像 $filter
这样的 url-query-parameters 。使用演示类/ Controller ,输出现在如下所示:
{
"@odata.context": "https://localhost:5001/api/v1/$metadata#WeatherForecast",
"value": [
{
"Id": 1,
"Date": "2021-05-22T14:00:18.9513586+02:00",
"TemperatureC": 36,
"Summary": "Sweltering"
},
{
"Id": 2,
"Date": "2021-05-23T14:00:21.6231763+02:00",
"TemperatureC": 44,
"Summary": "Chilly"
}
]
}
到目前为止,效果很好。
使用我的 API 的前端团队现在需要类似信封的东西..(是这样称呼的吗?)他们想要得到这样的结果:
{
"data": {
"type": "WeatherForecast",
"count": 2,
"items" : [
{
"Id": 1,
"Date": "2021-05-22T14:00:18.9513586+02:00",
"TemperatureC": 36,
"Summary": "Sweltering"
},
{
"Id": 2,
"Date": "2021-05-23T14:00:21.6231763+02:00",
"TemperatureC": 44,
"Summary": "Chilly"
}
]
},
"error": null
}
我有办法做到这一点吗?直接使用 OData 还是以其他方式?我不能简单地更改返回类型,因为 OData 需要 IQueryable<>
作为返回类型。这就是我尝试过的,但 Odata 无法过滤。
最佳答案
有多种方法可以实现此目的,但在直接跳到答案之前,我必须提到如果您自定义 API 返回的响应。由于非常规的响应格式,某些 OData 集成(例如 PowerBI、OData 客户端等)可能无法按预期工作。但如果您不打算将任何 OData 客户端与您的 API 集成,那么这对您来说应该不成问题。
另一件事是,也许您应该与公司的前端开发人员进行讨论,仅当他们在响应中收到非成功状态代码时才查找错误。他们应该期待 REST 标准错误响应(即 ProblemDetails )。他们建议的响应格式在 GraphQL world 中更常见。
回到主题,要自定义 OData 响应,您可以通过 Controller 的操作方法来完成。
public IActionResult Get(ODataQueryOptions<WeatherForecast> odataOptions)
{
var data = odataOptions.ApplyTo(_dbContext.Forecasts);
var odataFeature = HttpContext.ODataFeature();
var response = new WeatherApiEnvelope()
{
Data = new WeatherApiDataEnvelope()
{
Count = odataFeature.TotalCount,
Items = data,
Type = odataFeature.Path.GetEdmType().AsElementType().FullTypeName()
}
};
return Ok(response);
}
在此方法中,您必须删除 EnableQueryAttribute(如果存在)并返回 IActionResult 而不是 IQueryable,并将 ODataQueryOptions 作为参数添加到操作方法)。 ODataQueryOptions 是一个特定于 OData 的模型,它将携带来自查询字符串的查询信息,并且它具有 ApplyTo() 方法,该方法将 OData 查询(例如过滤器、投影等)应用于 IQueryable .
注意: OData 会执行额外的工作来获取总计数(如果您应用 $count=true),因为它必须在不考虑数据分页或($skip 和 $top)的情况下执行此操作查询选项。因此,当您调用 ApplyTo() 函数时,它将在 HttpContext 功能内的 IODataFeature 中设置总计数。
就我个人而言,我喜欢这种方法,因为它可以更好地控制我可以从方法返回的内容(例如,错误响应)。如果您想通过利用 OutputFormatters 将 IQueryable 保留为返回类型,还有另一种方法。 。简而言之,OutputFormatters 在action方法返回(包括过滤器)之后执行,其唯一目的是格式化响应并将其写入响应流中。
当您在 Startup 中调用 AddOData() 时,它会注入(inject) OData 所需的服务,包括 ODataOutputFormatter,它将格式化和序列化 OData 响应。在下面的示例中,我将通过添加新的 ODataOutputFormatter 来覆盖默认行为。
//Action Method
[EnableQuery]
public IQueryable<WeatherForecast> Get()
{
return _dbContext.Forecasts;
}
该操作方法由 EnableQueryAttribute 注释,该方法与我们在上一个示例中所做的操作完全相同(将查询应用于 IQueryable)。
注意:我的实现运行需要此注释,但您也可以更进一步,自己在输出格式化程序中应用查询。
public class WeatherforecastCustomOutputFormatter : ODataOutputFormatter
{
public WeatherforecastCustomOutputFormatter() : base(new List<ODataPayloadKind>
{
ODataPayloadKind.ResourceSet,
ODataPayloadKind.Resource
})
{
SupportedMediaTypes.Add(MediaTypeNames.Application.Json);
SupportedEncodings.Add(Encoding.UTF8);
}
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
var odataFeature = context.HttpContext.ODataFeature();
var response = new WeatherApiEnvelope()
{
Data = new WeatherApiDataEnvelope()
{
Count = odataFeature.TotalCount,
Items = context.Object,
Type = odataFeature.Path.GetEdmType().AsElementType().FullTypeName()
}
};
return context.HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response));
}
}
此自定义输出格式化程序继承自 ODataOutputFormatter 并重写 WriteResponseBodyAsync 以实现所需的行为。
注意:在 OData 中,有一个 ODataPayloadKind 概念,您可以阅读 here对于此格式化程序的范围,我仅包含 ResourceSet 和 Resource,它们应该涵盖返回对象列表或单个对象的需要。现在我们应该在 AddControllers() 中注入(inject)这个输出格式化程序。
public void ConfigureServices(IServiceCollection services)
{
services.AddOData(o => o.AddModel(GetEdmModel()).Filter().Select().OrderBy().Expand().SkipToken().Count());
services.AddControllers(options =>
{
options.OutputFormatters.Insert(0, new WeatherforecastCustomOutputFormatter());
});
}
这里,我在第一个索引中插入自定义 OutputFormatter,使其在现有索引之前运行,这不会删除现有的 ODataOutputFormatter,但会覆盖它,因为它将首先运行来处理请求。
注意:在这种情况下,在 AddControllers 之前调用 AddOData() 非常重要。而且我的格式化程序实现仅用于演示,您应该处理更多情况(例如,检查空值、处理错误、使用序列化选项等)
关于c# - 信封 Odata 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67636689/
我正在尝试检查 Entry 中是否存在重复项,并使用内联消息提醒用户该数字存在。 $(document).ready(function(){ $("#con1").blur(function(
我有一个基于类的 View 。我在引导模式上使用 Ajax。为了避免页面刷新,我想使用此类基于 View 返回 JSON 响应而不是 HTTP 响应,但我只看到了如何为基于函数的 View 返回 JS
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我有一个大型内部企业基于 Web 的应用程序在 IIS6 上运行 ASP.NET 3.5,生成 401 个“未经授权”响应,然后是 200 个“Ok”响应(如 Fiddler 所述)。我知道为什么会发
感谢您研究我的问题。 我有一个node/express服务器,配置了一个server.js文件,它调用urls.js,而urls.js又调用 Controller 来处理http请求,所有这些都配置相
当我使用以下命令时,我得到正确的 JSON 响应: $ curl --data "regno=&dob=&mobile=" https://vitacademics-rel.herokuapp.co
我有一个非常简单的 RESTful 服务,它通过 POST 接收一些表单数据,其目的是在云存储(Amazon S3、Azure Blob 存储等)中简单地保留文本主体(具有唯一 ID)作为一个文件..
UDP 不发送任何 ack,但它会发送任何响应吗? 我已经设置了客户端服务器UDP程序。如果我让客户端向不存在的服务器发送数据,那么客户端会收到任何响应吗? 我的假设是; 客户端 --> 广播服务器地
我有一个电梯项目,其中 有一个扩展 RestHelper 的类,看起来像这样 serve{ "api" / "mystuff" prefix { case a
我们正在寻求覆盖 Kong 错误响应结构并编写自定义消息(即用我们的自定义消息替换“超出 API 速率限制”、“无效的身份验证凭据”等)。 我们要找的错误响应结构(代码是自定义的内部错误代码,与HTT
我正在尝试监听 EKEventStoreChangedNotification 以检查当我的应用程序处于后台时日历是否已更改。 我在 View Controller 的 initWithNibMeth
我了解 javascript,并且正在学习 ASP.NET C# 我想要做什么(完成的是javascript): document.getElementById('divID-1'
是否可以过滤所有 har 对象并仅获取 POST 请求/响应?也许在初始化 BrowserMobProxyServer 期间是这样做的方法?我需要将 har 对象保存到文件中并上传到 har 查看器。
我正在尝试向 Oauth 的 API 发送响应。遗憾的是,Symfony2 文档在解释 $response->headers->set(...); 的所有不同部分方面做得很差。 这是我的 OauthC
我正在尝试测试用例来模拟 api 调用,并使用 python 响应来模拟 api 调用。 下面是我的模拟, with responses.RequestsMock() as rsps: url
在尝试在 Haskell 中进行一些领域驱动设计时,我发现自己遇到了这个问题: data FetchAccessories = FetchAccessories data AccessoriesRes
我正在与 ANT+ USB 棒连接,并用项目 react 器替换我自己天真的“MessageBus”,因为它看起来非常合适。 USB接口(interface)本质上是异步的(单独的输入/输出管道),我
我正在将项目迁移到AFNetworking 2.0。使用AFNetworking 1.0时,我编写了代码来记录控制台中的每个请求/响应。这是代码: -(AFHTTPRequestOperation *
我有以下代码段。 ajaxRequest.onreadystatechange = function(){ if(ajaxRequest.readyState == 4){
我有问题......我在 php 中有一个监听器脚本可以执行以下操作: if ($count != 1) {echo 'no';} else { echo "yes";} 因此它会回显"is"或“
我是一名优秀的程序员,十分优秀!