在 WebAPI 中的 null 上返回空 json
本文关键字:返回 json null WebAPI 中的 | 更新日期: 2023-09-27 17:55:35
当webApi返回空对象时,是否可以返回{ }而不是null?这是为了防止我的用户在解析响应时出现错误。并使响应成为有效的 Json 响应?
我知道我可以在任何地方手动设置它。当 null 是响应时,应返回一个空的 Json 对象。但是,有没有办法为每个响应自动执行此操作?
如果您正在构建一个 RESTful 服务,并且没有从资源返回的内容,我相信返回 404(未找到)比返回带有空正文的 200(OK)响应更正确。
HttpMessageHandler
对所有请求执行行为。 下面的示例是执行此操作的一种方法。 不过请注意,我很快就把它搞定了,它可能有很多边缘情况错误,但它应该让你知道如何做到这一点。
public class NullJsonHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (response.Content == null)
{
response.Content = new StringContent("{}");
} else if (response.Content is ObjectContent)
{
var objectContent = (ObjectContent) response.Content;
if (objectContent.Value == null)
{
response.Content = new StringContent("{}");
}
}
return response;
}
}
您可以通过执行以下操作来启用此处理程序,
config.MessageHandlers.Add(new NullJsonHandler());
感谢Darrel Miller,我现在使用这个解决方案。
WebApi在某些环境中再次弄乱StringContent "{}",因此通过HttpContent进行序列化。
/// <summary>
/// Sends HTTP content as JSON
/// </summary>
/// <remarks>Thanks to Darrel Miller</remarks>
/// <seealso cref="http://www.bizcoder.com/returning-raw-json-content-from-asp-net-web-api"/>
public class JsonContent : HttpContent
{
private readonly JToken jToken;
public JsonContent(String json) { jToken = JObject.Parse(json); }
public JsonContent(JToken value)
{
jToken = value;
Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
var jw = new JsonTextWriter(new StreamWriter(stream))
{
Formatting = Formatting.Indented
};
jToken.WriteTo(jw);
jw.Flush();
return Task.FromResult<object>(null);
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
}
派生自 OkResult 以利用 API 控制器中的 Ok()
public class OkJsonPatchResult : OkResult
{
readonly MediaTypeWithQualityHeaderValue acceptJson = new MediaTypeWithQualityHeaderValue("application/json");
public OkJsonPatchResult(HttpRequestMessage request) : base(request) { }
public OkJsonPatchResult(ApiController controller) : base(controller) { }
public override Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var accept = Request.Headers.Accept;
var jsonFormat = accept.Any(h => h.Equals(acceptJson));
if (jsonFormat)
{
return Task.FromResult(ExecuteResult());
}
else
{
return base.ExecuteAsync(cancellationToken);
}
}
public HttpResponseMessage ExecuteResult()
{
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new JsonContent("{}"),
RequestMessage = Request
};
}
}
在 API 控制器中覆盖 Ok()
public class BaseApiController : ApiController
{
protected override OkResult Ok()
{
return new OkJsonPatchResult(this);
}
}
也许更好的解决方案是使用自定义消息处理程序。
委派处理程序也可以跳过内部处理程序,直接 创建响应。
自定义消息处理程序:
public class NullJsonHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var updatedResponse = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = null
};
var response = await base.SendAsync(request, cancellationToken);
if (response.Content == null)
{
response.Content = new StringContent("{}");
}
else if (response.Content is ObjectContent)
{
var contents = await response.Content.ReadAsStringAsync();
if (contents.Contains("null"))
{
contents = contents.Replace("null", "{}");
}
updatedResponse.Content = new StringContent(contents,Encoding.UTF8,"application/json");
}
var tsc = new TaskCompletionSource<HttpResponseMessage>();
tsc.SetResult(updatedResponse);
return await tsc.Task;
}
}
注册处理程序:
在方法Global.asax
Application_Start()
文件中,通过添加以下代码来注册处理程序。
GlobalConfiguration.Configuration.MessageHandlers.Add(new NullJsonHandler());
现在,包含null
的所有Asp.NET Web API
响应都将替换为空Json
正文{}
。
引用:
- https://stackoverflow.com/a/22764608/2218697
- https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/http-message-handlers