1

I have created a controller using web api 2 in c#.

My controller method is a post and successfully completes, returning a 201

as shown below

But when the client receives the response, a 500 internal server error is returned.

Can anyone advise why this is happening?

I thought that once a controller was returning a value, the request was complete, this is obviously not the case.

    [HttpPost]
    [Route("PostProperty/{agentId}")]
    public async Task<IActionResult> PostProperty(int agentId, [FromBody]CreatePropertyRequestDto value)
    {
        string result = await _mediator.Send(new NewPropertyRequest() { NewProperty = value, AgentId = agentId });
        var c = CreatedAtRoute("getproperties", new { agentId, propertyIds = result }, result);
        return c;
    }

If I look in the output window I can see a 500 is being thrown, but I still don't know where or why. Please help

Application Insights Telemetry (unconfigured): {
    "name": "Microsoft.ApplicationInsights.Dev.Request",
    "time": "2018-08-13T20:51:39.9717971Z",
    "tags": {
        "ai.operation.name": "POST Properties/PostProperty [agentId]",
        "ai.cloud.roleInstance": "DESKTOP-DM70VVS",
        "ai.location.ip": "127.0.0.1",
        "ai.application.ver": "1.0.0.0",
        "ai.operation.id": "4d86444a-4e214be6ea456695",
        "ai.internal.nodeName": "DESKTOP-DM70VVS",
        "ai.internal.sdkVersion": "aspnet5c:2.1.1"
    },
    "data": {
        "baseType": "RequestData",
        "baseData": {
            "ver": 2,
            "id": "|4d86444a-4e214be6ea456695.",
            "name": "POST Properties/PostProperty [agentId]",
            "duration": "00:00:02.7187869",
            "success": false,
            "responseCode": "500",
            "url": "http://localhost:63103/api/properties/PostProperty/1",
            "properties": {
                "httpMethod": "POST",
                "AspNetCoreEnvironment": "Development",
                "DeveloperMode": "true"
            }
        }
    }
}

EDIT:

If I return an OK(result) a 200 is returned. So I can now confirm CreatedAtRoute() is the culprit. I have enabled app.UseDeveloperExceptionPage(); in Startup.cs and the showed me a helpful message

InvalidOperationException: No route matches the supplied values.

Reading this thread I can see the I must match the parameters of the action I am saying the item was created at.

updated post action

    [HttpPost]
    [Route("PostProperty/{agentId}")]
    public async Task<IActionResult> PostProperty(int agentId, [FromBody]CreatePropertyRequestDto value)
    {
        string result = await _mediator.Send(new NewPropertyRequest() { NewProperty = value, AgentId = agentId });
        return CreatedAtRoute($"GetProperty", new { agentId = agentId, propertyId = result });
    }

action the above is referencing

    [HttpGet]
    [Route("GetProperty/{agentId}/{propertyId}")]
    public async Task<IActionResult> GetProperty(int agentId, string propertyId)
    {
        if (agentId <= 0 || propertyId == null)
        {
            return BadRequest("agentId or propertyId was invalid. agentId must be a valid id and propertyId cannot be null");
        }

        IEnumerable<PropertyDto> properties = await GetPropertiesRequest(agentId, new List<string>(){ propertyId });
        PropertyDto property = properties.FirstOrDefault();
        if (property == null)
        {
            return NotFound();
        }
        return Ok(property);
    }

even with the update to my post action I still get

InvalidOperationException: No route matches the supplied values.

below also returns the same exception

CreatedAtRoute(routeName: "GetProperty", routeValues: new { agentId = agentId, propertyId = result }, value: result);

tony09uk
  • 2,841
  • 9
  • 45
  • 71
  • Use an exception filter to see the exception details. If I had to guess it is happening when the result is serialized to json (or whatever) for the client. Example: If you had a serializable property that had logic in it where the logic throws an exception. Another example is if you had an EF context that is relied on for the result that is disposed at the time the result is serialized, that would throw an exception. – Igor Aug 13 '18 at 21:01
  • Another answer might be that the result is 201 but the reroute to the result is causing the 500. Check the browser's network tab to be sure. – Igor Aug 13 '18 at 21:04
  • This is a duplicate of the issue covered in [this post on CreatedAtRoute()](https://stackoverflow.com/questions/36560239/asp-net-core-createdatroute-failure). Long story short, your'e calling the wrong `CreateAtRoute` method. If you're referring to a route which includes parameters then you should call the three-parameter version. – RAM Mar 20 '19 at 09:45

1 Answers1

1

I resolved my Issue by using CreatedAtAction(). In this scenario it is more suited that CreatedAtRoute as it is in the same controller. For a more detailed explanation of the differences read this thread

CreatedAtAction($"GetProperty", new { agentId = agentId, propertyId = result }, result);
tony09uk
  • 2,841
  • 9
  • 45
  • 71