当webApi返回空对象时,是否可以返回{}而不是null? 这样可以防止我的用户在解析响应时收到错误。并使响应成为有效的Json响应?在WebAPI中返回空json null
我知道我可以在任何地方手动设置它。当null是响应时,应该返回一个空的Json对象。但是,有没有办法为每个响应自动执行?
当webApi返回空对象时,是否可以返回{}而不是null? 这样可以防止我的用户在解析响应时收到错误。并使响应成为有效的Json响应?在WebAPI中返回空json null
我知道我可以在任何地方手动设置它。当null是响应时,应该返回一个空的Json对象。但是,有没有办法为每个响应自动执行?
如果你正在建设一个RESTful服务,并没有什么可从资源恢复,我相信,这将是更正确的返回404 (Not Found)而不是空的正文响应200 (OK)。
难道不会让人感到困惑吗?如在,如果服务器也关闭,你将得到一个404。你怎么能区分这个区别? – andrewjboyd
重要吗?作为客户端,您需要知道的是该URL没有资源。原因是一个实现细节。 –
我是第一个承认我不是专家,但是你不想告诉用户,如果你不能与服务器通信,你不能通信吗? 404对于获取单个对象是很好的,但是如果你要返回一个对象列表,不会更正确吗? – andrewjboyd
您可以使用HttpMessageHandler
对所有请求执行行为。下面的例子是一种方法。不过要注意的是,我很快就把它搞砸了,它可能有一堆边缘案例的bug,但它应该让你知道如何做到这一点。
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());
一段伟大的代码;我仍然会在接受的答案中遵循Mark Seemann的建议,而不是返回空的JSON对象,而是返回一个HTTP 404 Not Found消息。 –
@DavidKeaveny有时候204会比404更合适。想象一下URL'/ AccidentsToday'或'/ FailedTests' –
这些URI意味着集合的返回,在这种情况下,我会倾向于总是返回一个空的数组与HTTP 200.至于HTTP 204,我返回204s成功的PUT和DELETE操作;所以在我的NullJsonHandler中,我检查了请求方法以确保它是一个GET。 –
感谢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导出ApiController利用好()在ApiController
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
};
}
}
覆盖好()
public class BaseApiController : ApiController
{
protected override OkResult Ok()
{
return new OkJsonPatchResult(this);
}
}
如果你什么都没有返回,响应不应该null,但404(未找到)。 –
如果您使用WebApi来构建RESTful API,那么我同意@Mark Seemann。如果您只是使用webApi进行网址路由,并且不打算遵循REST实践,那么您可以返回任何您想要的内容。 – bsayegh
的确,我的项目正在尝试遵循REST实践,所以我同意@MarkSeemann。请把你的评论作为答案,我会接受它。 – spons