【问题标题】:OData cannot serialize a null resourceOData 无法序列化空资源
【发布时间】:2020-08-17 15:35:00
【问题描述】:

当 OData 查询中给出的参数没有找到结果时 - 您将如何处理返回的空值。如果碰巧没有结果,或者我只是返回 null 而不进行搜索,我会收到此异常。

错误:无法序列化空“资源”

应用程序引发了未处理的异常。 System.Runtime.Serialization.SerializationException:无法序列化 一个空的“资源”。在 Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectInline(对象 图,IEdmTypeReference 预期类型,ODataWriter 写入器, ODataSerializerContext writeContext) 在 Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteObject(对象 graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) 在 Microsoft.AspNet.OData.Formatter.ODataOutputFormatterHelper.WriteToStream(类型 类型、对象值、IEdmModel 模型、ODataVersion 版本、Uri baseAddress、MediaTypeHeaderValue 内容类型、IWebApiUrlHelper internalUrlHelper,IWebApi

我希望它返回一个空结果和一个 204 代码 - 但它返回一个带有 200 代码的空结果并在控制台中引发异常。

以下是控制器的一些示例代码:

[EnableQuery]
[ODataRoute("Topic/{id}")]
public TopicDto? GetTopic(string id)
{
    return _dbTableContext.Topic.Find(id);
}

【问题讨论】:

  • 为什么要返回 204 状态码?
  • @prd 204 表示请求正常,但未找到内容。我可以忍受 200 和空的结果,但我需要摆脱控制台中的异常。
  • 不,204 仅表示“无内容”,这将是通过 POST 成功创建对象的适当响应代码,在这种情况下,根据 REST,404 是正确的。
  • 知道了。关于异常处理的任何想法?
  • 希望SO 帖子上的解决方案可以帮助您。

标签: c# .net odata


【解决方案1】:

尝试从控制器方法返回 IActionResult 而不是可为空的 TopicDto,因为这样可以让您在 HTTP 响应方面更加灵活。

同样的原则也适用于 ASP.NET,但返回类型为 IHttpActionResult

TopicsController.cs

[ODataRoutePrefix("topics")]
public class TopicsController : ODataController
{
    private static readonly TopicViewModel[] _topics = new TopicViewModel[]
    {
        new TopicViewModel { Id = 1, Title = "Topic A"},
        new TopicViewModel { Id = 2, Title = "Topic B"},
        new TopicViewModel { Id = 3, Title = "Topic C"}
    };

    [EnableQuery]
    [ODataRoute("{id}")]
    public IActionResult Get(int id)
    {
        var topic = _topics.FirstOrDefault(x => x.Id == id);

        if (topic == null)
        {
            return NotFound();
        }

        return Ok(topic);
    }
}

使用 cURL 进行 API 测试

curl -i "https://localhost:44391/odata/topics(1)"
HTTP/2 200
content-type: application/json; odata.metadata=minimal; odata.streaming=true
server: Microsoft-IIS/10.0
odata-version: 4.0
x-powered-by: ASP.NET
date: Fri, 21 Aug 2020 09:28:42 GMT

{"@odata.context":"https://localhost:44391/odata/$metadata#Topics/$entity","Id":1,"Title":"Topic A"}
curl -i "https://localhost:44391/odata/topics(0)"
HTTP/2 404
server: Microsoft-IIS/10.0
x-powered-by: ASP.NET
date: Fri, 21 Aug 2020 09:28:54 GMT

【讨论】:

    猜你喜欢
    • 2016-01-26
    • 2014-02-19
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多