-1

I want to call an POST API Call and get some data. i use the swagger to do the call. The Problem is i got an Exception:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

This is on the razor page:

using var client = await httpClientHelper.GetHttpClientWithAccessToken();
var result = await client.PostJsonAsync<JobDetail>($"{_serviceClientOptions.Value.BetriebstoolServiceAddress}/api/AbaReport?scope={scope}&mandant={mandant}&reportname={reportname}", body);

Here you have the Controller

[HttpPost]
[Authorize(Roles = AppRoles.User)]
[ProducesResponseType(typeof(JobDetail), StatusCodes.Status200OK)]
[SwaggerOperation("StartReport")]
public async Task<JobDetail> StartReport(int scope, int mandant, string reportname, string body)
{
   var result = await _abaReportService.StartReport(scope, mandant, reportname, body);
   return result;
}

Now the Service

public async Task<JobDetail> StartReport(int scope, int mandant, string reportname, string body)
        {
            var getscope = await _abacusBetriebstoolDatastoreService.GetServerAccessByScopeIdAsync(scope);
            var abacusClient = await _clientFactory.CreateClient<AbacusApiClient>(getscope.ServerDNS, getscope.UserID, getscope.Passwort);
            var result = await abacusClient.GetReportAsync(mandant, reportname, body);
            return result;
        }

At a point in the generated Code from Swagger, it tries to deserialize to json

using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    using (var streamReader = new System.IO.StreamReader(responseStream))
                    using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader))
                    {
                        var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings);
                        var typedBody = serializer.Deserialize<T>(jsonTextReader); `<-- here ist the exception`
                        return new ObjectResponseResult<T>(typedBody, string.Empty);
                    }

Then i get the Exception!

And i see the point because when i try to call the api with Postman it looks like this: enter image description here

The "result" is an array but it should be an object like in the example in swagger: enter image description here

The response 'JobDetail' looks like this.

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.3.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class JobDetail 
    {
        /// <summary>The id of the user that last logged in or an empty string, if no-one logged in</summary>
        [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.Guid? Id { get; set; }
    
        [Newtonsoft.Json.JsonProperty("state", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
        public JobDetailState? State { get; set; }
    
        [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public string Message { get; set; }
    
        [Newtonsoft.Json.JsonProperty("finishedAt", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public System.DateTimeOffset? FinishedAt { get; set; }

        [Newtonsoft.Json.JsonProperty("result", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public TypedMap Result { get; set; }


    }
    
    [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.1.3.0 (Newtonsoft.Json v9.0.0.0)")]
    public partial class TypedMap 
    {
        [Newtonsoft.Json.JsonProperty("empty", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public bool? Empty { get; set; }
    
        [Newtonsoft.Json.JsonProperty("size", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public int? Size { get; set; }
    
    
    }

Why is the response an array? It should be a JSON object like in the swagger example.

I hope you can help me. Thank you :)

I searched a lot and found some solutions like this or that. But in my Problem i think the problem is in the generated code. i don't know

saschafehr
  • 47
  • 6
  • Wait a minute. You call an external api, and you don't like the result returned from there? – Roman Ryzhiy Dec 02 '22 at 12:36
  • @RomanRyzhiy I call an api from a internal server in the companie, but i didn't get why the response is different than the response in the swagger file. I mean the code is generated by the swagger. – saschafehr Dec 02 '22 at 12:40

1 Answers1

0

The result property in the swagger is not correct. Swagger says is should be an object, while the response has it as an array. You should change the type of public TypedMap Result { get; set; } to a List. (but a list of which items?)

theemee
  • 769
  • 2
  • 10
  • i cant change the code, because other API calls use this code and if i change it the other calls doesnt work anymore. but why is the result an empty array? i didn't get it – saschafehr Dec 02 '22 at 12:47
  • @saschafehr the API returns `"result": []` in the response as can be seen on your screenshot from postman – theemee Dec 02 '22 at 12:49
  • 1
    so the swagger schema that is generated on the api server is incorrect. You should contact the person responsible for it – theemee Dec 02 '22 at 12:51