5

I have a list of object as IEnumerable<IHit<Header>>, but .NET Core 3.0 is not emitting all information

this is when I return a single object IHit of the list obj.ElementAt(0)

{"explanation":null,"fields":null,"highlight":{},"id":"123","index":"ky","innerHits":{},"matchedQueries":[],"nested":null, "primaryTerm":null, "routing":null, "score":10.98915, "sequenceNumber":null, "sorts":[],"source":{"timeStamp":"2019-05-16T06:16:07Z", "result":"PASS","testTimeStart":"20190516141559","testTimeEnd":"20190516141607","barcode":"XXRX8762"},"type":"_doc","version":0}

but when I return the list itself:

[{"explanation":null,"fields":null,"highlight":{},"innerHits":{},"matchedQueries":[],"nested":null,"score":10.98915,"sorts":[]}]

also when I try explicitly to call JsonSerializer

string s = JsonSerializer.Serialize(result, typeof(IEnumerable<IHit<Header>>), obj);

To Wrap Up:

  1. WebApi is working correctly and returning the object serialized correctly if a signle object:

    public IHit<Header> Get(string id)

but when a list, then it is not.

public IEnumerable<IHit<Header>> GetAll()

I tried IEnumerable, IList, List and all the same result!

  1. JsonSerializer is working neither with a single object nor with a list
Abdulkarim Kanaan
  • 1,703
  • 4
  • 20
  • 32

5 Answers5

20

I still don't know the weird behavior I faced due to emitting a single object while not the case of list.

but here how solved the problem based on @poke's answer and @NeilMacMullen's comment

  1. add package Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. in Startup.cs, add

    services.AddControllers().AddNewtonsoftJson();

Abdulkarim Kanaan
  • 1,703
  • 4
  • 20
  • 32
  • 4
    I personally find it ridiculous that Microsoft rolls out its half-baked serializer as a default solution for .NET Core 3.0 projects. I mean, It indeed is twice as fast as Newtonsoft, but it comes with the price of having less than half the functionality mutilated. – mg30rg Mar 02 '20 at 13:19
  • 2
    As of today, Jun, 2022, I am using dotnet 6, this is not working.. very frustrated – B.W Jun 23 '22 at 06:13
  • @B.W, I have used the code on .NET Core 3.0, don't know about .NET 6 – Abdulkarim Kanaan Jun 24 '22 at 02:55
5

Add the attribute [JsonInclude] with .Net 6 for it to serialize lists

e.g.

   [JsonInclude]
   public List<StaffEarningDetail> EarningDetails;
Daniel Pamich
  • 971
  • 10
  • 7
2

If your are using Newtonsoft.Json then do as follows:

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
        );

    ...
}

If you are not using Newtonsoft.Json then do as follows:

public void ConfigureServices(IServiceCollection services)
{
    ...

   services.AddMvc().AddJsonOptions(option => option.JsonSerializerOptions.MaxDepth = 2);

    ...
}

For more details : Related data and serializatione

TanvirArjel
  • 30,049
  • 14
  • 78
  • 114
0

JsonSerializer likely does not know how to serialize IHit<T>. I would propose one of:

Getting the JSON string response from Elasticsearch, using either

  1. the low level client, exposed on the high level client as the .LowLevel property. You can serialize a high level request type using PostData.Serializable(request)
  2. using OnRequestCompleted() and setting DisableDirectStreaming() on the request or globally on ConnectionSettings

or

Mapping the response from Elasticsearch to another type that JsonSerializer will serialize.

Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • thanks I will try this regarding JsonSerializer, but why WebApi is able to return a single object `IHit
    ` serialized correctly, but when returning the whole list `IEnumerable>` then it is not!
    – Abdulkarim Kanaan Sep 27 '19 at 03:16
  • I don't know off the top of my head, I'm afraid – Russ Cam Sep 27 '19 at 03:19
0

In my case I've mistakenly written internal set function at ViewModel class properties as follows;

public int CampaignServiceFee { get; internal set; }

just removed the internal keyword so that outside of class, JsonSerializer, can set values.

Omer Çiftçi
  • 46
  • 1
  • 5