pizycki
pizycki

Reputation: 1350

Model state is valid, but status 400 is returned

I'm trying to figure out what's going on with my routing. Here's the action in controller with two routes.

public enum AvaibleScheduleEventParticipantGroupType
{
    Teachers,
    ...
}

[HttpGet]
[Route("groups/{type}/{id?}", Order = 1)]
[Route("groups/{type}", Order = 2)]
[ResponseType(typeof(IEnumerable))]
public IEnumerable GetParticipantGroupForScheduleEvent(AvaibleScheduleEventParticipantGroupType type, Guid? id = null)
{
    var request = new ScheduleEventParticipantGroupRequest
    {
        Type = type,
        Id = id
    };
    return GettingParticipantGroupForScheduleEventService.HandleGroupRequest(request);
}

After some time spent on playing around with route paths, I finally found a solution that doesn't end up with message "No action was found on the controller" when I try navigating

http://localhost:65358/api/scheduleevents/groups/teachers

Now I'm getting 400 status altough I have no validation on my parameters. Weird. I've looked on what's happening in IIS with Output window and found this:

w3wp.exe Information: 0 : Request, Method=GET, Url=http://localhost:65358/api/scheduleevents/groups/teachers, Message='http://localhost:65358/api/scheduleevents/groups/teachers'
w3wp.exe Information: 0 : Message='ScheduleEvent', Operation=DefaultHttpControllerSelector.SelectController
w3wp.exe Information: 0 : Message='Nau.Dzienniczek.Api.Areas.Schedule.Controllers.ScheduleEventController', Operation=DefaultHttpControllerActivator.Create
w3wp.exe Information: 0 : Message='Nau.Dzienniczek.Api.Areas.Schedule.Controllers.ScheduleEventController', Operation=HttpControllerDescriptor.CreateController
w3wp.exe Information: 0 : Message='Selected action 'GetParticipantGroupForScheduleEvent(AvaibleScheduleEventParticipantGroupType type, Nullable`1 id)'', Operation=ApiControllerActionSelector.SelectAction
w3wp.exe Information: 0 : Operation=AuthorizeAttribute.OnAuthorizationAsync
w3wp.exe Information: 0 : Message='Parameter 'type' bound to the value 'Teachers'', Operation=ModelBinderParameterBinding.ExecuteBindingAsync
w3wp.exe Information: 0 : Message='Parameter 'id' bound to the value 'null'', Operation=ModelBinderParameterBinding.ExecuteBindingAsync
w3wp.exe Information: 0 : Message='Model state is valid. Values: type=Teachers, id=null', Operation=HttpActionBinding.ExecuteBindingAsync
w3wp.exe Information: 0 : Operation=ValidateModelAttribute.OnActionExecutingAsync, Status=400 (BadRequest)
w3wp.exe Information: 0 : Operation=ScheduleEventController.ExecuteAsync, Status=400 (BadRequest)
w3wp.exe Information: 0 : Operation=DependencyScopeHandler.SendAsync, Status=400 (BadRequest)
w3wp.exe Information: 0 : Response, Status=400 (BadRequest), Method=GET, Url=http://localhost:65358/api/scheduleevents/groups/teachers, Message='Content-type='none', content-length=unknown'
w3wp.exe Information: 0 : Operation=ScheduleEventController.Dispose

Look closely at the 6th line from the bottom.

'Model state is valid. Values: type=Teachers, id=null'

which is followed by

Operation=ValidateModelAttribute.OnActionExecutingAsync, Status=400 (BadRequest)

So what's going on?

Url below works like a charm.

http://localhost:65358/api/scheduleevents/groups/teachers/1e7cb4f9-8e6a-4127-9505-5fad9978ebc6

Upvotes: 1

Views: 72

Answers (1)

Stephen Brickner
Stephen Brickner

Reputation: 2602

I don't believe webAPI can handle the conversion of enums in a route so I would change that to a string. Also, because your id parameter is optional you can condense your route.

[HttpGet, Route("api/scheduleevents/groups/{type}/{id:guid?}")]
public IHttpActionResult GetParticipantGroupForScheduleEvent(string type, Guid? id = null)
{
    try
    {
       var request = new ScheduleEventParticipantGroupRequest
       {
           Type = type,
           Id = id
       };

      //assuming this returns an object or list of objects
       var response = GettingParticipantGroupForScheduleEventService.HandleGroupRequest(request);

       return Ok(response);
    }
    catch
    {
       return InternalServerError();
    }
}

Edit: I just noticed the route you are calling is: http://localhost:65358/api/scheduleevents/groups/teachers

Unless you are using a routePrefix on your class of api/scheduleevents you will need to add it to your route. I added it in the answer above.

Upvotes: 1

Related Questions