Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
300 changes: 300 additions & 0 deletions aspnetcore/fundamentals/openapi/openapi-comments.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<ItemGroup>
<PackageReference Include="Some.Package" Version="10.0.0"
GeneratePathProperty="true" />
</ItemGroup>

<ItemGroup>
<AdditionalFiles Include="$(PkgSome_Package)/lib/net10.0/Some.Package.xml" />
</ItemGroup>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.2.25161.17" />
<PackageReference Include="Scalar.AspNetCore" Version="2.0.30" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\models\Models.csproj" />
</ItemGroup>

</Project>

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.2.25161.17" />
<PackageReference Include="Scalar.AspNetCore" Version="2.0.30" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\models\Models.csproj" />
</ItemGroup>

<Target Name="DisableCompileTimeOpenApiXmlGenerator" BeforeTargets="CoreCompile">
<ItemGroup>
<Analyzer Remove="$(PkgMicrosoft_AspNetCore_OpenApi)/analyzers/dotnet/cs/Microsoft.AspNetCore.OpenApi.SourceGenerators.dll" />
Comment on lines +19 to +21
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using Remove in the project file, that is,
<Analyzer Remove="$(PkgMicrosoft_AspNetCore_OpenApi)/analyzers/dotnet/cs/Microsoft.AspNetCore.OpenApi.SourceGenerators.dll" />

DOES NOT prevent \aspnet-openapi-xml\api\obj\Debug\net10.0\Api.xml from being generated.

</ItemGroup>
</Target>

</Project>

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-preview.2.25161.17" />
<PackageReference Include="Scalar.AspNetCore" Version="2.0.30" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\models\Models.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@Api_HostAddress = http://localhost:5052

GET {{Api_HostAddress}}/weatherforecast/
Accept: application/json

### Project Board Endpoints ###

### Get all project boards
GET {{Api_HostAddress}}/api/projectboards
Accept: application/json

### Get project board by ID
GET {{Api_HostAddress}}/api/projectboards/1
Accept: application/json

### Create a new project board
POST {{Api_HostAddress}}/api/projectboards
Content-Type: application/json

{
"name": "Website Redesign",
"description": "Tasks for redesigning the company website"
}

### Update a project board
PUT {{Api_HostAddress}}/api/projectboards/1
Content-Type: application/json

{
"name": "Website Redesign v2",
"description": "Updated tasks for redesigning the company website"
}

### Delete a project board
DELETE {{Api_HostAddress}}/api/projectboards/1


### Todo Endpoints ###

### Get all todos for a project board
GET {{Api_HostAddress}}/api/projectboards/1/todos
Accept: application/json

### Get a specific todo by ID
GET {{Api_HostAddress}}/api/projectboards/1/todos/1
Accept: application/json

### Create a new todo
POST {{Api_HostAddress}}/api/projectboards/1/todos
Content-Type: application/json

{
"title": "Design new homepage",
"description": "Create wireframes for the new homepage design",
"isComplete": false,
"priority": 2,
"dueDate": "2025-03-20T00:00:00Z"
}

### Update a todo
PUT {{Api_HostAddress}}/api/projectboards/1/todos/1
Content-Type: application/json

{
"title": "Design new homepage with feedback",
"description": "Update wireframes based on stakeholder feedback",
"isComplete": true,
"priority": 3,
"dueDate": "2025-03-25T00:00:00Z"
}

### Delete a todo
DELETE {{Api_HostAddress}}/api/projectboards/1/todos/1
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Api;
using Scalar.AspNetCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference();
}

app.Map("/", () => Results.Redirect("/scalar/v1"));
app.MapProjectBoardApis();
app.MapTodoApis();

app.Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
using Models;
using Microsoft.AspNetCore.Http.HttpResults;
using System.ComponentModel.DataAnnotations;

namespace Api;

/// <summary>
/// Extension methods for mapping ProjectBoard-related API endpoints.
/// </summary>
public static class ProjectBoardApis
{
// In-memory storage for demo purposes
internal static readonly List<ProjectBoard> Boards = new();
private static int _nextBoardId = 1;

/// <summary>
/// Maps all ProjectBoard related API endpoints to the application.
/// </summary>
/// <param name="app">The endpoint route builder.</param>
public static void MapProjectBoardApis(this IEndpointRouteBuilder app)
{
var boardGroup = app.MapGroup("/api/projectboards")
.WithTags("Project Boards")
.WithOpenApi();

// Project Board endpoints
boardGroup.MapGet("/", GetAllProjectBoards);
boardGroup.MapGet("/{id}", GetProjectBoardById);
boardGroup.MapPost("/", CreateProjectBoard);
boardGroup.MapPut("/{id}", UpdateProjectBoard);
boardGroup.MapDelete("/{id}", DeleteProjectBoard);
}

/// <summary>
/// Retrieves all project boards.
/// </summary>
/// <returns>A collection of all project boards.</returns>
/// <response code="200">Returns the list of project boards.</response>
public static IResult GetAllProjectBoards()
{
return Results.Ok(Boards);
}

// <snippet_1>
/// <summary>
/// Retrieves a specific project board by ID.
/// </summary>
/// <param name="id">The ID of the project board to retrieve.</param>
/// <returns>The requested project board.</returns>
/// <response code="200">Returns the requested project board.</response>
/// <response code="404">If the project board is not found.</response>
public static IResult GetProjectBoardById(int id)
{
var board = Boards.FirstOrDefault(b => b.Id == id);
if (board == null)
{
return Results.NotFound();
}
return Results.Ok(board);
}
// </snippet_1>

/// <summary>
/// Creates a new project board.
/// </summary>
/// <param name="board">The project board to create.</param>
/// <returns>The newly created project board.</returns>
/// <response code="201">Returns the newly created project board.</response>
/// <response code="400">If the project board data is invalid.</response>
public static IResult CreateProjectBoard(ProjectBoard board)
{
board.Id = _nextBoardId++;
board.CreatedAt = DateTime.UtcNow;
Boards.Add(board);

return Results.Created($"/api/projectboards/{board.Id}", board);
}

/// <summary>
/// Updates an existing project board.
/// </summary>
/// <param name="id">The ID of the project board to update.</param>
/// <param name="updatedBoard">The updated project board data.</param>
/// <returns>No content if successful.</returns>
/// <response code="204">If the update was successful.</response>
/// <response code="400">If the project board data is invalid.</response>
/// <response code="404">If the project board is not found.</response>
public static IResult UpdateProjectBoard(int id, ProjectBoard updatedBoard)
{
var board = Boards.FirstOrDefault(b => b.Id == id);
if (board == null)
{
return Results.NotFound();
}

board.Name = updatedBoard.Name;
board.Description = updatedBoard.Description;

return Results.NoContent();
}

/// <summary>
/// Deletes a project board.
/// </summary>
/// <param name="id">The ID of the project board to delete.</param>
/// <returns>No content if successful.</returns>
/// <response code="204">If the deletion was successful.</response>
/// <response code="404">If the project board is not found.</response>
public static IResult DeleteProjectBoard(int id)
{
var board = Boards.FirstOrDefault(b => b.Id == id);
if (board == null)
{
return Results.NotFound();
}

Boards.Remove(board);
return Results.NoContent();
}
}
Loading