Reputation: 7577
When the arguments given in an OData query does not find a result - how will you be handling the returned null value. I get this exception if it happends that there are no retult or I simply return null without ever searching.
Error: Cannot serialize a null 'Resource'
An unhandled exception was thrown by the application. System.Runtime.Serialization.SerializationException: Cannot serialize a null 'Resource'. at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext) at Microsoft.AspNet.OData.Formatter.Serialization.ODataResourceSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) at Microsoft.AspNet.OData.Formatter.ODataOutputFormatterHelper.WriteToStream(Type type, Object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, IWebApiUrlHelper internaUrlHelper, IWebApi
I would expect it to return an empty result and a 204 code - but it returns an empty result with a 200 code and throws the exception in the console.
Here is some sample code from the controller:
[EnableQuery]
[ODataRoute("Topic/{id}")]
public TopicDto? GetTopic(string id)
{
return _dbTableContext.Topic.Find(id);
}
Upvotes: 3
Views: 2073
Reputation: 970
In my case - I had an object where one of it's property was a List<> and it was set to null.
When I returned this object back - from response to my Serializer - it failed with the above exception.
Simply initializing the property to a new List<> would solve your problem.
Upvotes: 0
Reputation: 2321
Try returning an IActionResult
instead of a nullable TopicDto
from your controller methods, as this leaves you with more flexibility regarding HTTP responses.
The same principle applies to ASP.NET but with
IHttpActionResult
as the return type.
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);
}
}
API Test using cURL
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
Upvotes: 3