/// <summary>
/// updates information of a job
/// </summary>
/// <param name="job"></param>
/// <returns>Ok or Error</returns>
/// <example>
/// {
/// "info_id": 1,
/// "some_other_id": 2
/// }
/// </example>
[HttpPost]
[Route("api/job/update")]
public IHttpActionResult update(Models.Job job) {
}
//the model
public class Job {
[Required(AllowEmptyStrings = false)]
[Range(1, Int64.MaxValue)]
public Int64 info_id { get; set; }
public Int64? some_other_id{ get; set; }
public DateTime last_log_time { get; set; }
}
Imagine the setup above. I would like to show the example JSON written inside the doc block of update in the documentation. However, there is shown the serialized JSON of an object typed Job with default values instead.
I don't want developers to think they could or should provide last_log_time to function update. This property shall be shown in a response message, but not sent to the api.
How can I customize the examples for the requests formats per function? Ideally I would state it inside the doc block as shown (the API should only take requests in JSON-format), or maybe per annotations on the properties of the Job-class.
How can we hide a property in WebAPI? the answer provodided here does not help because, as stated above, last_log_time shall be given in the response. If I annotate it with [IgnoreDataMember] it will be ignored globally.
You can add [ApiExplorerSettings(IgnoreApi = true)] to your last_log_time property, but it only hides last_log_time in body parameters.
If you want to hide in sample format, you need customize source code of method WriteSampleObjectUsingFormatter at file Areas\HelpPage\SampleGeneration\HelpPageSampleGenerator.cs
Related
Is there a way how to make Swashbuckle take the XML Comments for properties which hide those in the base class?
class Base {
/// <summary>
/// This comment shows in swagger UI.
/// </summary>
public int Value { get; set; }
}
class Model: Base {
/// <summary>
/// This comment is not visible in swagger UI.
/// </summary>
public new int Value { get; set; }
}
Is there any workaround, e.g. using a kind of SchemaFilter?
UPDATED
The above simple example works as expected.
Our problem is probably caused by a wrong configuration of the IncludeXmlComments option as our models come from multiple assemblies.
I found a related discussion on GitHub
I'm having this issue with ModelState validation, since I'm using a model with an attribute decorated with [Required] attribute but it never gets invalid, even on null.
Here's the controller:
[HttpPost("x/{sampleString}")]
[ProducesResponseType(StatusCodes.Status303SeeOther)]
public IActionResult Post(string sampleString, SponsorContractorFilterModel model)
{
if (!ModelState.IsValid)
return StatusCode(BadRequest("Model sent is not valid").StatusCode.GetValueOrDefault());
//do stuff, add location on header and send back the 303.
return StatusCode(StatusCodes.Status303SeeOther);
}
And the model is pretty simple:
public class SponsorContractorFilterModel
{
/// <summary>
/// Initializes a new instance of the <see cref="SponsorContractorFilterModel"/> class.
/// </summary>
public SponsorContractorFilterModel()
{
}
/// <summary>
/// Sponsor number.
/// </summary>
[Required]
public int? AnImportantNumber { get; set; }
public List<int> SomeIds { get; set; }
//few more attributes not been decorated on purpose.
}
The thing is that when I send with postman a model object without an "AnImportantNumber" or explicitly null in neither of the cases it shows that is invalid. And when I debug it I can see its actually mapped as null.
I would suggest to use [BindRequired] attribute to make sure data were present on the request. There is No source for a model property section in the docs that explains a bit.
Also there is a bit older article [Required] and [BindRequired] in ASP.NET Core MVC written by Filip W. about that subject. It may be good starting point/inspiration too.
Hope it helps
This is my model:
public class JQueryDataTableParamModel
{
/// <summary>
/// Request sequence number sent by DataTable, same value must be returned in response
/// </summary>
[Required]
public string sEcho { get; set; }
/// <summary>
/// Text used for filtering
/// </summary>
[Required]
public string sSearch { get; set; }
}
This is my ActionResult:
public ActionResult VolumeOverviewHandler([Bind(Include = "sEcho")]JQueryDataTableParamModel param)
My question is does the Required attribute on 2nd property going to create issues in this case?
Nice question, the Bind attribute will improve the performance by only bind properties which you needed.
You can check if this will cause any problem by using the ModelState entity.
Inside your controller, the first thing you do is checking the ModelState use the following instruction:
if(!ModelState.IsValid){ throw new someException(); or return BadRequest("Model Is Not Valid");}
If you're ModelState is valid. You can consider that there are no problems, and proceed with whatever you want to do.
I have a controller method that looks like this:
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
[Produces("application/json")]
public async Task<IActionResult> GenerateTokenAsync([FromForm]TokenParameters tokenParameters)
TokenParameters looks like this:
public class TokenParameters
{
/// <summary>
/// Specifies the grant type. Must be "password".
/// </summary>
[Required]
public GrantType? grant_type
{
get;
set;
}
/// <summary>
/// Specifies the username.
/// </summary>
[Required]
public string username
{
get;
set;
}
/// <summary>
/// Specifies the password.
/// </summary>
[Required]
public string password
{
get;
set;
}
}
Everything works fine, but the Swagger UI is not picking up the /// triple slash comments for the members. My other controllers use FromBody and /// triple slash comments work fine with those. Seems like the model section at the bottom picks up the comments, but I'm talking about the model description in the light green section when I look at the controller.
I've looked in the schema registry, and the descriptions are indeed there.
EDIT: Using Swashbuckle 5.0 Beta.
EDIT #2: It also doesn't seem to pick up the example values from the schema registry for form parameters either.
Any ideas?
Make sure that your project has the Generate xml documentation option checked.
Also, when you configure Swagger, make sure to have it include the xml comments.
// Register the Swagger generator, defining one or more Swagger documents
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v2", new Info { Title = "my API", Version = "v2" });
// Set the comments path for the Swagger JSON and UI.
var basePath = PlatformServices.Default.Application.ApplicationBasePath;
var xmlPath = Path.Combine(basePath, "myapp.xml");
c.IncludeXmlComments(xmlPath);
});
I too had this issue. My issue was that I was not including the correct XML documentation files. I was including only the web application XML documentation while I had my "creation options" object that was being created from the form data defined in another assembly. Once I had this assembly producing XML documentation and including it in the swagger configuration I was able to get descriptions for each form field item.
Here is my controller method handling the POST from the client:
/// <summary>
/// Create a new very complex object.
/// </summary>
/// <param name="creationOptions">Very complex creation options</param>
/// <returns>The very complex object as a data transfer object.</returns>
[HttpPost]
[Consumes("application/x-www-form-urlencoded")]
public async Task<IActionResult> CreateVeryComplexObject([FromForm] VeryComplexObjectCreationOptions creationOptions) { }
When adding the swagger services I included the documentation from both assemblies:
services.AddSwaggerGen(config =>
{
// All my other swagger configuration here...
config.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, "MyService.API.Web.xml"));
config.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, "MyService.API.Contracts.xml"));
});
This is on Swashbuckle 4.0.1.
In a C# Web Api controller, how do I decorate an action's parameter, so that a default value for that parameter shows up in swagger?
You can try something like below, I am considering input object for Action method as Product as you have not mentioned anything explicitly in your question.
You can use ///<example>value </example> tag in your Request Field.
public class Product
{
public int Id { get; set; }
///<summary>
///</summary>
///<example>example value</example>
public string Description { get; set; }
}
2.
For Default value of parameters in Action Methods, you can directly use as below:
/// <summary>
/// Action Method Summary
/// </summary>
/// <param name="Description">example value</param>