我的一个web api项目-使用.NetCore 2.1-我想有一个返回消息的约定。所有成功的结果对象都必须用result
对象封装,所有错误和诸如此类的东西都必须使result
为空,并填充resultCode
和resultMessage
字段。我应该用格式化程序在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));
}