1

I'm currently migrating an API from ASP.NET Web API to ASP.NET Core. My old API had an endpoint accepting a list as part of the body:

public IHttpActionResult Post(MyModel model)
{
    ...
}

public class MyModel
{
    public List<SomeObject> SomeObjects { get; set; }
}

I have some consumers of this API that was able to post the following JSON:

POST /post
{
    "someObjects": {}
}

Of course, this should have been:

POST /post
{
    "someObjects": []
}

but ASP.NET Web API model binding accepted this (setting someObjects to null I guess`).

When doing the same with ASP.NET Core, I get the following error when posting the same JSON to the API:

Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[SomeObject]'

Again, I totally understand why the error is there. I need to be backwards compatible, so can anyone help? I guess I need a custom model binder or something to allow the empty object to be converted into null or an empty list?

5
  • Don't know the answer but maybe I can point you in the direction of setting your own JsonSerializerSettings newtonsoft.com/json/help/html/… Commented Sep 12, 2019 at 7:35
  • setting someObjects to null I guess` is this the actual current behavior? Commented Sep 12, 2019 at 7:47
  • No, the current behavior is that the request fails with the error I posted in the question. Commented Sep 12, 2019 at 7:50
  • I mean the "legacy" behavior; was the property set to null on your ASPNET WebApi? Commented Sep 12, 2019 at 8:05
  • I don't remember. The issue here isn't ASP.NET Web API though. I simply want to allow {} as a valid value for List<SomeObject. If it's null or an empty list in ASP.NET Core, I can handle that in the new version. Commented Sep 12, 2019 at 8:22

1 Answer 1

1

This is not a clean solution but you can write a custom JsonConverter for List<SomeObject> and return null or an empty list when not a list:

public class CustomConverter : JsonConverter<List<SomeObject>>
{
    public override List<SomeObject> ReadJson(JsonReader reader, Type objectType, List<SomeObject> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        if (token.Type == JTokenType.Array)
        {
            return token.ToObject<List<SomeObject>>();
        }
        return null;
    }

    public override void WriteJson(JsonWriter writer, List<SomeObject> value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
}

public class MyModel
{
    [JsonConverter(typeof(CustomConverter))]
    public List<SomeObject> SomeObjects { get; set; }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I have fixed the issue using your code but implemented the ReadJson method without exceptions. With your permission, I will update your code and mark it as the answer?
Sure, I was just too lazy to implement the best solution :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.