0
votes

I created an API app without the full blown MVC template. However, a POST request with body always fails with Internal Server Error.

I followed the exact same steps here for a stateful service:

I created a project with the Stateful Service template in Visual Studio. I added a Kestrel listener as described here:

protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
    return new ServiceReplicaListener[]
    {
        new ServiceReplicaListener(serviceContext =>
            new KestrelCommunicationListener(serviceContext, (url, listener) =>
                new WebHostBuilder()
                    .UseKestrel()
                    .ConfigureServices(
                         services => services
                             .AddSingleton<StatefulServiceContext>(serviceContext)
                             .AddSingleton<IReliableStateManager>(this.StateManager))
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
                    .UseStartup<Startup>()
                    .UseUrls(url)
                    .Build()
            ))
    };
}

Then, I added a Startup class and a test controller: internal class Startup { public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddMvcCore(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMvc(); } }

[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
{

    [HttpGet("Read1")]
    public async Task<ActionResult<string>> Read1()
    {
        return "asd";
    }
    [HttpPost("Read2")]
    public async Task<ActionResult<string>> Read2()
    {
        return "asd";
    }
    [HttpPost("Read3")]
    public async Task<ActionResult<MyOutput>> Read([FromBody]MyInput input)
    {
       
        var a = new MyOutput();
        a.Value= "asdasd";
        return a;
        
    }
}

using System.Runtime.Serialization;
[DataContract]
public class MyInput
{

    [DataMember]
    public string Value{ get; }

    public MyInput(string val)
    {
        Value= val;
    }
}

When I make a request to these 3 endpoints, the /Read1 and /Read2 requests work fine. However, /Read3 request fails with Internal Server Error on the client side and I tried to put a breakpoint into controller but for /Read3 it will never hit it. That makes me think the deserialization is not working.

I send the requests from Insomnia. A simple POST request with a content-type header set to "application/json" and JSON body:

{
    "Value": "cat"
}

What might be causing this?

1
The error is in the request you are sending the server and not in the controller in the client which is a response. The server doesn't like the format of the request and returning an error message. Then in your client when you process the error message you are failing. The solution is to fix the request, not the response.jdweng
@jdweng thanks for the reply. However, it is a very simple POST request. I am not sure what might be going wrong in the request. (I updated the issue with a sample request)Sammy
The format of a request depends on the server requirements. We do not know the server requirements and if two requests work and third does not you are not meeting the server requirements and we cannot help.jdweng
Yes, but for the other 2 requests, there is no body. So, it might be an issue related to deserialization as wellSammy
No. It is an internal server error. So either the server doesn't want a body or the body is not in the correct format.jdweng

1 Answers

0
votes

In my case, I was missing the json formatter:

services.AddMvcCore().AddJsonFormatters();

Maybe it helps someone.