Reputation: 1846
I write my Web API controllers in a non-standard way where I get the parameters as dynamic objects.
This creates an issue with NSwag. Because there are no parameters in the method definition, NSwag cannot generate what is needed.
I wonder if there is any option to use NSwag in this situation. Maybe there are some attributes that I can add to the methods so that NSwag will be able to generate the API?
[HttpPost]
[ActionName("create-account")]
public IHttpActionResult CreateAccount()
{
var body = Request.Content.ReadAsStringAsync().Result;
dynamic json = Utils.GetJsonBody(body);
if (!Utils.GetJsonPropertyValueByPropertyName<String>(json, "email", out String email))
{
return Content(HttpStatusCode.BadRequest, "Please provide a valid email.".AsApiMessageResult());
}
if (!Utils.GetJsonPropertyValueByPropertyName<String>(json, "name", out String name))
{
return Content(HttpStatusCode.BadRequest, "Please provide an account name.".AsApiMessageResult());
}
if (!Utils.GetJsonPropertyValueByPropertyName<String>(json, "domain", out String domain))
{
return Content(HttpStatusCode.BadRequest, "Please provide a valid domain.".AsApiMessageResult());
}
Upvotes: 1
Views: 3453
Reputation: 32704
The thing about Swagger is that it uses the signatures of your method to generate its documentation of how your code works. Bypassing all the normal Web API and choosing to read the raw HTTP request means that Swagger can't see what you're doing, making it difficult for it to automatically determine what your code does. The technique you're doing with reading the raw request and using dynamic has a number of other disadvantages.
Instead, we should define a proper model to post to our API. This will allow Web API to do its job, the model binder will handle converting the request into an instance of CreateAccountRequest.
public class CreateAccountRequest
{
public string Email { get; set; }
public string Name { get; set; }
public string Domain { get; set; }
}
Then we can have our action method take this an instance of this class as a parameter.
[HttpPost]
[ActionName("create-account")]
public IHttpActionResult CreateAccount(CreateAccountRequest request)
{
//now here you can validate the request if you want
}
Swagger should be able to understand this method now, allowing NSwag to generate a useful client.
Note that instead of doing custom C# validation, you should look into the built in tools that Web API provides for model validation. Then all you would need to do is check the ModelState, rather than manually checking each parameter. Other tooling can also look at the attributes of your models, enhancing the tooling experience.
Upvotes: 4