Thomas Nørgaard
Thomas Nørgaard

Reputation: 135

ServiceStack Swagger body

I'm struggling getting Swagger to present my ServiceStack service correctly.

I would like to see an UserId string as a form parameter and a PrivateCustomer object as a body parameter, but keep getting a body parameter with BOTH the UserId and the PrivateCustomer, despite UserId also appearing as a separate input field.

Here's my code: enter image description here

And here's the result in Swagger: enter image description here

How do I get rid of the UserId in the body?

Thanks a lot!

Upvotes: 3

Views: 519

Answers (1)

mythz
mythz

Reputation: 143284

The [Api*] annotations are only for documenting your API, they do not impact your API's behavior, e.g. the request body is always expected to be the entire Request DTO and you can't have both "form" and "body" parameter types sent at the same time, i.e. there's only 1 Request Body and when using "form" only the form variables will be sent.

If you wanted to separate them you could add UserId to the query string and exclude them from appearing in the model schema with:

[Route("/CreatePrivateCustomer", "POST")]
public class CreatePrivateCustomerRequest
{
    [ApiMember(IsRequired = true, ParameterType = "query", ExcludeInSchema = true)]
    public string UserId { get; set; }

    [ApiMember(IsRequired = true, ParameterType = "model")]
    public PrivateCustomer Customer { get; set; }
}

This will separate the variables and send UserId in the queryString and the request of the DTO in the Request Body as JSON, e.g:

POST /CreatePrivateCustomer?UserId=1
Content-Type: application/json

{"Customer":{"CustomerNumber":1,...}}

Although generally if you want required parameters separated from the Request Body you would put them in the path, e.g:

[Route("/CreatePrivateCustomer/{UserId}", "POST")]
public class CreatePrivateCustomerRequest
{
    [ApiMember(IsRequired = true, ParameterType = "path", ExcludeInSchema = true)]
    public string UserId { get; set; }

    [ApiMember(IsRequired = true, ParameterType = "model")]
    public PrivateCustomer Customer { get; set; }
}

and if you don't want the PrivateCustomer properties nested you would add them directly on the Request DTO, e.g:

[Route("/CreatePrivateCustomer/{UserId}", "POST")]
public class CreatePrivateCustomerRequest
{
    [ApiMember(IsRequired = true, ParameterType = "path", ExcludeInSchema = true)]
    public string UserId { get; set; }

    public int CustomerNumber { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Upvotes: 1

Related Questions