Skip to content

Protobuf formatter: No response with large results #215

@M-AV

Description

@M-AV

I have an ASP.NET Core Web Api (.NET 5) using the Protobuf formatter to serialize responses. When my controller returns a large amount of data the client gets a 200 OK response, but no data.

I reproduced it by creating a new empty web api project (running locally with iisexpress). Adding version 3.0.0 of WebApiContrib.Core.Formatter.Protobuf and configuring it in the Startup like this:

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddControllers(opt => 
        {
            opt.FormatterMappings.SetMediaTypeMappingForFormat("protobuf", MediaTypeHeaderValue.Parse("application/x-protobuf"));
        })
        .AddProtobufFormatters();
}

Then I modified the default WeatherForecastController to look like this:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    public WeatherForecastController(ILogger<WeatherForecastController> logger) { }

    [HttpGet]
    public IActionResult Get([FromQuery] int count)
    {
        var time = DateTime.UtcNow;
        var result = Enumerable.Range(0, count).Select(i => new Dto()
        {
            Prop1 = 1,
            Prop2 = time,
            Prop3 = time,
            Prop4 = 1,
            Prop5 = 1,
            Prop6 = "Some string",
            Prop7 = 1,
            Prop8 = 1,
            Prop9 = 1,
            Prop10 = 1,

        }).ToList();
        return Ok(result);
    }

    [DataContract]
    public class Dto
    {
        [DataMember(Order = 1)]
        public int Prop1 { get; set; }
        [DataMember(Order = 2)]
        public DateTime Prop2 { get; set; }
        [DataMember(Order = 3)]
        public DateTime Prop3 { get; set; }
        [DataMember(Order = 4)]
        public int Prop4 { get; set; }
        [DataMember(Order = 5)]
        public short Prop5 { get; set; }
        [DataMember(Order = 6)]
        public string Prop6 { get; set; }
        [DataMember(Order = 7)]
        public int Prop7 { get; set; }
        [DataMember(Order = 8)]
        public int Prop8 { get; set; }
        [DataMember(Order = 9)]
        public decimal Prop9 { get; set; }
        [DataMember(Order = 10)]
        public int Prop10 { get; set; }

        public Dto() { }
    }
}

I query this endpoint with the code below. It works fine when count is small. If I increase it to 5.000.000 or more it doesn't. It works if I use Json.

var handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate };

var client = new HttpClient(handler) { BaseAddress = new Uri("http://localhost:18345"), DefaultRequestHeaders = { Accept = { new MediaTypeWithQualityHeaderValue("application/x-protobuf") } }, Timeout = TimeSpan.FromMinutes(10) };
int count = 500000;        
var formattableString = $"weatherforecast?count={count}";

var response = await client.GetAsync(formattableString);
response.EnsureSuccessStatusCode();

var responseStream = await response.Content.ReadAsStreamAsync();
var dtos = Serializer.Deserialize<IEnumerable<Dto>>(responseStream).ToArray();

image
image

Using Fiddler, I can see the data is not returned from the API
image

Am I doing something wrong or is there an issue here? Why am I getting a 200 OK even though I'm not getting a response?

Appreciate any help

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions