asp.net-core-webapiprotobuf-net

Posting a request from POSTMAN with protobuf in the body


I would like to POST a request from postman with a protobuf message in the body, and hit the breakpoint in my service method, with the protobuf message deserialized to a c# object, but this is not happening. I get the following error in postman.

415 Unsupported media type

The GET request works correctly and hits the breakpoint in the service and returns data in protobuf format, but the POST does not even hit the breakpoint. I take the returned protobuf format and add it to the body of the POST to test the post, but this does not work.

Here is the service code for GET and POST.

 [ApiController]
public class ItemController : ControllerBase
{
    [HttpGet]
    [Produces("application/x-protobuf")]
    public IActionResult Get()
    {
        List<Item> items = new List<Item>
        {
            new Item{Id=1, Name= "Item 1", Value=4},
            new Item{Id=2, Name= "Item 2", Value=3 }
        };
        return Ok(items);
    }


    [HttpPost]
    [Consumes("application/x-protobuf", "application/json")]
    [Produces("application/x-protobuf")]
    public IActionResult Post([FromBody]  Item myItem)
    {
        
        List<Item> items = new List<Item>
        {
            new Item{Id=1, Name= "Item 5", Value=4},
            new Item{Id=2, Name= "Item 7", Value=3 }
        };

        items.Add(myItem);
        return Ok(items);
    }
}

The model looks like this:

using ProtoBuf;

namespace ProtobufService
{
    [ProtoContract]
    public class Item
    {
        [ProtoMember(1)]
        public int Id { get; set; }
        [ProtoMember(2)]
        public string Name { get; set; }
        [ProtoMember(3)]
        public long Value { get; set; }
    }
}

The libraries in the service project are...

enter image description here

POST pamarms

POST body

GET request working ok

I have written a console app which is a test client. This client performs the GET and POST correctly and breakpoints are getting hit. Here is the code for the client...

 private static async Task GetProtobufData(HttpClient client)
 {       
    var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:5163/api/item");
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));
    var result = await client.SendAsync(request);
    var tables = ProtoBuf.Serializer.Deserialize<Item[]>(await result.Content.ReadAsStreamAsync());


    string itemproto = Serializer.GetProto<Item>();
    Console.WriteLine(itemproto);

    Console.WriteLine("the returned from get value is: " + tables[1].Name);
    Console.ReadLine();
}

private static async Task PostProtobufData(HttpClient client)
{
    MemoryStream stream = new MemoryStream();
    ProtoBuf.Serializer.Serialize<Item>(stream, new Item
    {
        Name = "kpatel",
        Id=5566677,
        Value=1234
    });
    
    var data = stream.ToArray();
    var content = new ByteArrayContent(data, 0, data.Length);
    content.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf");
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:5163/api/item")
    {
        Content = content
    };

    var responseForPost = await client.SendAsync(request);
    var result = ProtoBuf.Serializer.Deserialize<Item[]>(await responseForPost.Content.ReadAsStreamAsync());

    Console.WriteLine("the returned value is: " + result[0].Name);
    Console.ReadLine();
}

The code in the client is hitting the breakpoints and returning expected data.

I would like to know how to test a POST using postman.


Solution

  • I resolved this by moving the ContentType from params to Headers tab, and pasting in the protobuf response from the Get into the body (raw) as a parameter for my service endpoint.

    the param tab now looks like...

    enter image description here

    the headers tab...

    enter image description here

    the body using raw for endpoint param... enter image description here

    the response from service endpoint in json...

    enter image description here

    The breakpoint and the request param deserialized...

    enter image description here