在WebAPI中返回null上的空json

当webApi返回空对象时,是否可以返回{}而不是null? 这样可以防止我的用户在解析响应时出错。 并使响应成为有效的Json响应?

我知道我可以手动设置它。 当null是响应时,应该返回一个空的Json对象。 但是,有没有办法自动为每个响应做到这一点?

如果您正在构建RESTful服务,并且没有从资源返回任何内容,我相信返回404(未找到)比使用空主体的200(OK)响应更正确。

您可以使用HttpMessageHandler对所有请求执行行为。 以下示例是一种方法。 但是请注意,我很快就掀起了这个问题,它可能有一堆边缘错误,但它应该让你知道它是如何完成的。

  public class NullJsonHandler : DelegatingHandler { protected override async Task 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进行序列化。

 ///  /// Sends HTTP content as JSON ///  /// Thanks to Darrel Miller ///  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(null); } protected override bool TryComputeLength(out long length) { length = -1; return false; } } 

源自OkResult以利用ApiController中的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 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 }; } } 

在ApiController中覆盖Ok()

 public class BaseApiController : ApiController { protected override OkResult Ok() { return new OkJsonPatchResult(this); } } 

更好的解决方案

可能更好的解决方案是使用自定义消息处理程序。

委托处理程序也可以跳过内部处理程序并直接创建响应。

自定义消息处理程序:

 public class NullJsonHandler : DelegatingHandler { protected override async Task 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(); tsc.SetResult(updatedResponse); return await tsc.Task; } } 

注册处理程序:

Application_Start()方法内的Global.asax文件中,通过添加以下代码来注册您的Handler。

 GlobalConfiguration.Configuration.MessageHandlers.Add(new NullJsonHandler()); 

现在,所有包含nullAsp.NET Web API响应将被替换为空的Json body {}

参考文献:

1。

2。