Skip to content

Commit

Permalink
Merge pull request #22 from jiripeli/prerelease
Browse files Browse the repository at this point in the history
1.0.14-pre.1 - examples for a parameter type other than body + examples
  • Loading branch information
vaclavnovotny authored May 18, 2024
2 parents e9f0cc3 + 343d379 commit 65114a5
Show file tree
Hide file tree
Showing 22 changed files with 313 additions and 82 deletions.
87 changes: 78 additions & 9 deletions samples/NSwagWithExamples/Controllers/PeopleController.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using NSwag.Examples;
using NSwagWithExamples.Models;
using NSwagWithExamples.Models.Examples;
using NSwagWithExamples.Models.Examples.Persons.Requests;

namespace NSwagWithExamples.Controllers;

Expand All @@ -14,34 +17,100 @@ namespace NSwagWithExamples.Controllers;
[ProducesResponseType(StatusCodes.Status500InternalServerError, Type = typeof(CustomInternalError))]
public class PeopleController : ControllerBase
{
private static readonly ConcurrentDictionary<int, Person> People = new ConcurrentDictionary<int, Person>();
private static readonly object Lock = new object();

private static void NewPerson(Person person)
{
lock (Lock)
{
person.Id = People.Keys.Any() ? People.Keys.Max() + 1 : 1;
People.TryAdd(person.Id, person);
}
}

static PeopleController()
{
NewPerson(new Person("Franta", "Jetel"));
NewPerson(new Person("Jára", "Cimrman"));
NewPerson(new Person("Jindra", "Hlaváček"));
NewPerson(new Person("Vilma", "Böhmová"));
NewPerson(new Person("Emanuel", "Pecháček"));
NewPerson(new Person("Inspektor", "Trachta"));
NewPerson(new Person("Inspektor", "Klečka"));
NewPerson(new Person("první", "podezřelý"));
NewPerson(new Person("druhý", "podezřelý"));
NewPerson(new Person("třetí", "podezřelý"));
NewPerson(new Person("čtvrtý", "podezřelý"));
}

[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List<Person>))]
public IActionResult GetPeople() => Ok(new List<Person>());
[EndpointSpecificExample(typeof(PersonAge18Example), typeof(PersonAge69Example), ParameterName = "minAge", ExampleType = ExampleType.Request)]
[EndpointSpecificExample(typeof(PersonTextExample1), typeof(PersonTextExample2), typeof(PersonTextExample3), ParameterName = "searchText", ExampleType = ExampleType.Request)]
public IActionResult GetPeople([FromQuery] int? minAge = null, [FromQuery] string searchText = null)
{
if (minAge == null && string.IsNullOrEmpty(searchText))
return Ok(People);

if (minAge == null)
return Ok(People.Values.Where(p => $"{p.FirstName}~{p.LastName}".Contains(searchText, StringComparison.CurrentCultureIgnoreCase)));

if (string.IsNullOrEmpty(searchText))
return Ok(People.Values.Where(p => p.Age >= minAge));

return Ok(People.Values.Where(p => p.Age >= minAge && $"{p.FirstName}~{p.LastName}".Contains(searchText, StringComparison.CurrentCultureIgnoreCase)));
}

[HttpGet("count")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(int))]
public IActionResult GetNumberOfPeople() => Ok(0);
public IActionResult GetNumberOfPeople() => Ok(People.Count);

[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Person))]
[ProducesResponseType(StatusCodes.Status500InternalServerError, Type = typeof(CustomInternalErrorOnMethodLevel))]
public IActionResult GetPerson([FromRoute] int id) => Ok(new Person());
public IActionResult GetPerson([FromRoute] int id)
{
if (People.TryGetValue(id, out Person person))
return Ok(person);

return NotFound();
}

[HttpGet("{id}/age")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(int))]
[ProducesResponseType(StatusCodes.Status500InternalServerError, Type = typeof(CustomInternalErrorOnMethodLevel))]
[EndpointSpecificExample(typeof(PersonSpecificAgeExample))]
public IActionResult GetPersonAge([FromRoute] int id) => Ok(50);
public IActionResult GetPersonAge([FromRoute] int id)
{
if (People.TryGetValue(id, out Person person))
return Ok(person.Age);

return NotFound();
}

[HttpGet("{id}/birth")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(DateTime))]
[ProducesResponseType(StatusCodes.Status500InternalServerError, Type = typeof(CustomInternalErrorOnMethodLevel))]
public IActionResult GetPersonBirth([FromRoute] int id) => Ok(DateTime.UtcNow);
public IActionResult GetPersonBirth([FromRoute] int id)
{
if (People.TryGetValue(id, out Person person))
return Ok(person.BirthDay);

return NotFound();
}

[HttpPost]
public IActionResult CreatePerson([FromBody][BindRequired] Person person) =>
// create person logic
Ok();
public IActionResult CreatePerson([FromBody] Person person)
{
if (person == null)
return BadRequest("{person} is null");

if (person.BirthDay.Year < 1800 || person.BirthDay > DateTime.Now)
return BadRequest($"BirthDay is out of range (1800/01/01..today)");

NewPerson(person);
return Ok(person.Id);
}

[HttpPost("from-file")]
public IActionResult CreatePersonFromFile([FromForm] IFormFile file) => Ok();
Expand Down
4 changes: 2 additions & 2 deletions samples/NSwagWithExamples/Models/Examples/BrnoExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public City GetExample()
Id = 5,
Name = "Brno",
People = new List<Person> {
new Person {Id = 1, FirstName = "Henry", LastName = "Cavill"},
new Person {Id = 2, FirstName = "John", LastName = "Doe"}
new Person(1, "Henry", "Cavill"),
new Person(2, "John", "Doe")
}
};
}
Expand Down
4 changes: 2 additions & 2 deletions samples/NSwagWithExamples/Models/Examples/CitiesExample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public List<City> GetExample()
Id = 5,
Name = "Brno",
People = new List<Person> {
new Person {Id = 1, FirstName = "Henry", LastName = "Cavill"},
new Person {Id = 2, FirstName = "John", LastName = "Doe"}
new Person (1, "Henry", "Cavill"),
new Person (2, "John", "Doe")
}
}
};
Expand Down

This file was deleted.

41 changes: 0 additions & 41 deletions samples/NSwagWithExamples/Models/Examples/PersonExample.cs

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples;
namespace NSwagWithExamples.Models.Examples.Persons;

public class PeopleExample : IExampleProvider<List<Person>>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using NSwag.Examples;
using RandomNameGeneratorLibrary;

namespace NSwagWithExamples.Models.Examples.Persons;

public class PersonExample : IExampleProvider<Person>
{
private readonly IPersonNameGenerator _nameGenerator;

// Use dependency injection to resolve any registered service
public PersonExample(IPersonNameGenerator nameGenerator)
{
_nameGenerator = nameGenerator;
}

public Person GetExample() => new Person(
_nameGenerator.GenerateRandomFirstName(),
_nameGenerator.GenerateRandomLastName()
);
}

public class PersonBirthExample : IExampleProvider<DateTime>
{
public DateTime GetExample() => DateTime.UtcNow.Date;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples.Persons.Requests;

[ExampleAnnotation(Name = "Age 18", ExampleType = ExampleType.Request)]
public class PersonAge18Example : IExampleProvider<int>
{
public int GetExample() => 18;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples.Persons.Requests;

[ExampleAnnotation(Name = "Age 69", ExampleType = ExampleType.Request)]
public class PersonAge69Example : IExampleProvider<int>
{
public int GetExample() => 69;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples.Persons.Requests;

[ExampleAnnotation(Name = "Cindy", ExampleType = ExampleType.Request)]
public class PersonRequestExampleCindy : IExampleProvider<Person>
{
public Person GetExample() => new Person("Cindy", "Crowford", new DateTime(1966, 2, 20));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples.Persons.Requests;

[ExampleAnnotation(Name = "Tom", ExampleType = ExampleType.Request)]
public class PersonRequestExampleTom : IExampleProvider<Person>
{
public Person GetExample() => new Person("Tom", "Hanks", new DateTime(1956, 7, 9));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples.Persons.Requests;

[ExampleAnnotation(Name = "Search text 'inspektor'", ExampleType = ExampleType.Request)]
public class PersonTextExample1 : IExampleProvider<string>
{
public string GetExample() => "inspektor";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples.Persons.Requests;

[ExampleAnnotation(Name = "Search text 'podez'", ExampleType = ExampleType.Request)]
public class PersonTextExample2 : IExampleProvider<string>
{
public string GetExample() => "podez";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using NSwag.Examples;

namespace NSwagWithExamples.Models.Examples.Persons.Requests;

[ExampleAnnotation(Name = "Search text 'ra'", ExampleType = ExampleType.Request)]
public class PersonTextExample3 : IExampleProvider<string>
{
public string GetExample() => "ra";
}
39 changes: 37 additions & 2 deletions samples/NSwagWithExamples/Models/Person.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
namespace NSwagWithExamples.Models;
using System;

namespace NSwagWithExamples.Models;

public class Person
{
private static readonly Random Random = new Random(DateTime.Now.Microsecond);

public string FirstName { get; set; }
public int Id { get; set; }
public int Id { get; internal set; }
public string LastName { get; set; }
public DateTime BirthDay { get; set; }

public Person()
{
}
public Person(int id, string firstName, string lastName, DateTime? birthDay = null)
{
Id = id;
FirstName = firstName;
LastName = lastName;
BirthDay = birthDay ?? new DateTime(Random.Next(1920, DateTime.Now.Year), Random.Next(1, 13), Random.Next(1, 29));
}

public Person(string firstName, string lastName, DateTime? birthDay = null)
{
FirstName = firstName;
LastName = lastName;
BirthDay = birthDay ?? new DateTime(Random.Next(1920, DateTime.Now.Year), Random.Next(1, 13), Random.Next(1, 29));
}

public int Age
{
get
{
var today = DateTime.Today;
var age = today.Year - BirthDay.Year;
if (BirthDay.Date > today.AddYears(-age)) age--;
return age;
}
}

}
1 change: 1 addition & 0 deletions samples/NSwagWithExamples/NSwagWithExamples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<IsPackable>false</IsPackable>
<Version>1.0.14</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
5 changes: 5 additions & 0 deletions src/NSwag.Examples/EndpointSpecificExampleAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public class EndpointSpecificExampleAttribute : Attribute

public ExampleType ExampleType { get; set; } = ExampleType.Both;

/// <summary>
/// A parameter name is required for a parameter kind other than body.<br />
/// </summary>
public string? ParameterName { get; set; }

public EndpointSpecificExampleAttribute(Type exampleType, params Type[] additionalExampleTypes)
{
if (exampleType.GetInterfaces().All(i => i.IsGenericType && i.GetGenericTypeDefinition() != typeof(IExampleProvider<>)))
Expand Down
Loading

0 comments on commit 65114a5

Please sign in to comment.