如何封装web api响应传统的int.netcore api



我的一个web api项目-使用.NetCore 2.1-我想有一个返回消息的约定。所有成功的结果对象都必须用result对象封装,所有错误和诸如此类的东西都必须使result为空,并填充resultCoderesultMessage字段。我应该用格式化程序在startup.cs上执行此操作,还是创建一个响应生成器类,而不使用[ApiController]属性标记功能,如Ok(), NotFound() etc..,我真的想使用。我找不到任何相关文件或指南。这是我的代码:

[HttpGet]
[Produces("applicaiton/json")]
public IActionResult GetValues()
{
var toRet = new[] {"value1", "value2"};
return Ok(toRet);
}

这个代码块返回["value1","value2"],但我需要它像这个一样

{
"result": ["value1","value2"],
"resultCode": 200,
"resultMessage": "OK"
}

我如何以及在哪里可以达成这个约定?

编辑

请原谅我的示例代码。我将在回复中使用自定义错误代码。200 OK很可能是

{
"result" : "some value",
"resultCode" : 0,
"resultMessage" : "All values returned"
}

400 Bad Request将是

{
"result" : null,
"resultCode" : 20468,
"resultMessage" : "Dont have any value to show!"
}

假设您定义了一个具有重写WriteResponseBodyAsync:的新JsonOutputFormatter

public class SuperJsonOutputFormatter:JsonOutputFormatter
{
public SuperJsonOutputFormatter(
JsonSerializerSettings serializerSettings, 
ArrayPool<char> charPool) : base(serializerSettings, charPool)
{
}
public override async Task WriteResponseBodyAsync(
OutputFormatterWriteContext context, 
Encoding selectedEncoding)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (selectedEncoding == null)
throw new ArgumentNullException(nameof(selectedEncoding));
using (TextWriter writer = 
context.WriterFactory(
context.HttpContext.Response.Body, 
selectedEncoding))
{
var rewrittenValue = new
{
result = context.Object, 
resultCode = context.HttpContext.Response.StatusCode, 
resultMessage =
((HttpStatusCode) context.HttpContext.Response.StatusCode)
.ToString()
};
this.WriteObject(writer, rewrittenValue);
await writer.FlushAsync();
}
}
}

您可以取消注册旧的JsonOutputFormatter,并在Startup.ConfigureServices中用新的屁股格式化程序替换它,如下所示:

public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(opts =>
{
var oldFormatter = 
opts.OutputFormatters.OfType<JsonOutputFormatter>().Single();
opts.OutputFormatters.Remove(oldFormatter);
var replacementJsonOutputFormatter = 
new SuperJsonOutputFormatter(oldFormatter.PublicSerializerSettings,
ArrayPool<char>.Shared);
opts.OutputFormatters.Add(replacementJsonOutputFormatter);
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

并保持控制器中的代码与以前完全相同。

当然,如果(例如(客户端只接受XML,那么内容协商将跳过这个格式化程序。如果您只想要JSON输出,请取消注册任何其他输出格式化程序。

状态代码200 OK是指HTTP状态代码,它是HTTP协议的一部分。状态代码是HTTP头的一部分,而结果是内容的一部分。

由于这是HTTP协议的一部分,因此它受到普遍支持,您几乎没有理由在消息中重复此信息。HTTP连接的另一端将能够从标头中提取此信息。它还将有一个处理状态代码的基础设施,比如一个网络浏览器,它将在3xx响应后自动重定向,并在4xx响应上显示错误页面。

所有这些对于像您正在构建的REST服务也是如此。REST是基于HTTP的,因此使用该协议的功能没有错。因此,我建议您考虑一下,如果您真的需要在内容中提供这些信息。

如果你仍然想把这些信息作为消息内容的一部分,你可以自己手动添加:

public class ResultMessage<T> {
public T Result { get; set; }
public HttpStatusCode ResultCode { get; set; }
public string ResultMessage { get; set; }
}
ResultMessage<T> GetResultMessage<T>(T value, HttpStatusCode resultCode) {
return new ResultMessage<T> {
Result = value,
ResultCode = resultCode,
ResultMessage = resultCode.ToString()
};
}
[HttpGet]
[Produces("application/json")]
public IActionResult GetValues()
{
var toRet = new[] {"value1", "value2"};
return Ok(GetResultMessage(toRet, HttpStatusCode.OK));
}

最新更新