Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Web API controller definition doc #6003

Merged
merged 33 commits into from
Apr 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
39c56df
Add Web API controller definition doc
scottaddie Apr 17, 2018
f6cb514
Remove wwwroot folder reference from csproj file
scottaddie Apr 17, 2018
28ba86e
Verbiage tweaks
scottaddie Apr 17, 2018
e5ab1c9
Add info about FromForm inference
scottaddie Apr 17, 2018
2183485
Bold the attribute names
scottaddie Apr 17, 2018
c7f4d30
Add TOC entries
scottaddie Apr 17, 2018
403f2f1
Change link ordering in TOC
scottaddie Apr 17, 2018
18faa47
Add note about IntelliSense
scottaddie Apr 18, 2018
484b1ab
Major sample app changes
scottaddie Apr 18, 2018
2a5bd8a
Fix code snippet line numbers
scottaddie Apr 18, 2018
10c9c3f
Minor verbiage tweaks
scottaddie Apr 18, 2018
e9a1da9
Add a README file
scottaddie Apr 18, 2018
d279a55
Add TestController.cs
scottaddie Apr 18, 2018
4bffbfd
Verbiage changes
scottaddie Apr 18, 2018
5763966
Shorten wording
scottaddie Apr 18, 2018
6dd85f1
Change wording
scottaddie Apr 18, 2018
0e2bba9
Minor edit
scottaddie Apr 19, 2018
ecdf8ca
React to feedback
scottaddie Apr 23, 2018
3932ec7
Add attributes table
scottaddie Apr 23, 2018
11ae6cb
Verbiage tweaks
scottaddie Apr 23, 2018
7e883bc
querystring -> query string
scottaddie Apr 23, 2018
916c999
Minor edit
scottaddie Apr 23, 2018
f010d89
Add 2.1 controller samples
scottaddie Apr 23, 2018
da136e5
Fix invalid moniker names
scottaddie Apr 23, 2018
f58d262
Update code sample to 2.1
scottaddie Apr 23, 2018
b2371af
Update line number
scottaddie Apr 23, 2018
5401a72
Convert uppercase W to lowercase
scottaddie Apr 23, 2018
c2658cc
React to feedback
scottaddie Apr 24, 2018
e790d33
Update sample app's README file
scottaddie Apr 24, 2018
5d45cb5
Project file cleanup
scottaddie Apr 24, 2018
6b2192e
Replace word
scottaddie Apr 24, 2018
7a43402
Remove MVC views from sample app
scottaddie Apr 24, 2018
c1b589d
Derive from ControllerBase instead of Controller
scottaddie Apr 24, 2018
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
12 changes: 12 additions & 0 deletions aspnetcore/web-api/define-controller/samples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ASP.NET Core Web API Controller Sample

This sample app consists of the following projects:

- **WebApiSample.Api**: An ASP.NET Core 2.1 project targeting .NET Core 2.1.
- **WebApiSample.Api.Pre21**: An ASP.NET Core 2.0 project targeting .NET Core 2.0.
- **WebApiSample.DataAccess**: A .NET Standard 2.0 class library serving as a data access tier for the 2 Web API projects.

This sample illustrates variations of Web API controller creation:

- [Derive class from ControllerBase](https://docs.microsoft.com/en-us/aspnet/core/web-api/define-controller#derive-class-from-controllerbase)
- [Annotate class with ApiControllerAttribute](https://docs.microsoft.com/en-us/aspnet/core/web-api/define-controller#annotate-class-with-apicontrollerattribute)
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebApiSample.DataAccess.Models;
using WebApiSample.DataAccess.Repositories;

namespace WebApiSample.Api.Controllers
{
#region snippet_PetsController
[Produces("application/json")]
[Route("api/[controller]")]
public class PetsController : ControllerBase
{
private readonly PetsRepository _repository;

public PetsController(PetsRepository repository)
{
_repository = repository;
}

[HttpGet]
[ProducesResponseType(typeof(IEnumerable<Pet>), 200)]
public IActionResult Get()
{
return Ok(_repository.GetPets());
}

[HttpGet("{id}")]
[ProducesResponseType(typeof(Pet), 200)]
[ProducesResponseType(404)]
public IActionResult GetById(int id)
{
if (!_repository.TryGetPet(id, out var pet))
{
return NotFound();
}

return Ok(pet);
}

[HttpPost]
[ProducesResponseType(typeof(Pet), 201)]
[ProducesResponseType(400)]
public async Task<IActionResult> CreateAsync([FromBody] Pet pet)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

await _repository.AddPetAsync(pet);

return CreatedAtAction(nameof(GetById),
new { id = pet.Id }, pet);
}
}
#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebApiSample.DataAccess.Models;
using WebApiSample.DataAccess.Repositories;

namespace WebApiSample.Api.Pre21.Controllers
{
#region snippet_ControllerSignature
[Route("api/[controller]")]
public class ProductsController : ControllerBase
#endregion
{
private readonly ProductsRepository _repository;

public ProductsController(ProductsRepository repository)
{
_repository = repository;
}

#region snippet_GetById
[HttpGet("{id}")]
[ProducesResponseType(typeof(Product), 200)]
[ProducesResponseType(404)]
public IActionResult GetById(int id)
{
if (!_repository.TryGetProduct(id, out var product))
{
return NotFound();
}

return Ok(product);
}
#endregion

#region snippet_BindingSourceAttributes
[HttpGet]
[ProducesResponseType(typeof(List<Product>), 200)]
public IActionResult Get([FromQuery] bool discontinuedOnly = false)
{
List<Product> products = null;

if (discontinuedOnly)
{
products = _repository.GetDiscontinuedProducts();
}
else
{
products = _repository.GetProducts();
}

return Ok(products);
}
#endregion

[HttpPost]
[ProducesResponseType(typeof(Product), 201)]
[ProducesResponseType(400)]
public async Task<IActionResult> CreateAsync([FromBody] Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

await _repository.AddProductAsync(product);

return CreatedAtAction(nameof(GetById),
new { id = product.Id }, product);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace WebApiSample.Api.Pre21
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}

public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
using WebApiSample.DataAccess;
using WebApiSample.DataAccess.Repositories;

namespace WebApiSample.Api.Pre21
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ProductsRepository>();
services.AddScoped<PetsRepository>();

services.AddDbContext<ProductContext>(opt =>
opt.UseInMemoryDatabase("ProductInventory"));
services.AddDbContext<PetContext>(opt =>
opt.UseInMemoryDatabase("PetInventory"));

services.AddMvc();

services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Title = "ASP.NET Core Pre-2.1 Web API",
Version = "v1"
});

c.DescribeAllEnumsAsStrings();
});
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}

app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API v1");
c.RoutePrefix = string.Empty;
});
app.UseMvcWithDefaultRoute();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<ProjectUISubcaption>&lt;= ASP.NET Core 2.0</ProjectUISubcaption>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.7" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.4.0" />
</ItemGroup>

<ItemGroup>
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WebApiSample.DataAccess\WebApiSample.DataAccess.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Mvc;

namespace WebApiSample.Api.Controllers
{
#region snippet_ControllerSignature
[ApiController]
public class MyBaseController
{
}
#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebApiSample.DataAccess.Models;
using WebApiSample.DataAccess.Repositories;

namespace WebApiSample.Api.Controllers
{
#region snippet_PetsController
[Produces("application/json")]
[Route("api/[controller]")]
public class PetsController : ControllerBase
{
private readonly PetsRepository _repository;

public PetsController(PetsRepository repository)
{
_repository = repository;
}

[HttpGet]
public ActionResult<List<Pet>> Get()
{
return _repository.GetPets();
}

[HttpGet("{id}")]
[ProducesResponseType(404)]
public ActionResult<Pet> GetById(int id)
{
if (!_repository.TryGetPet(id, out var pet))
{
return NotFound();
}

return pet;
}

[HttpPost]
[ProducesResponseType(400)]
public async Task<ActionResult<Pet>> CreateAsync(Pet pet)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

await _repository.AddPetAsync(pet);

return CreatedAtAction(nameof(GetById),
new { id = pet.Id }, pet);
}
}
#endregion
}
Loading