Menu

ASP.net Core 2 RESTful API on Cloud9

3rd December 2017 - developer, Development, dotnetcore, linux

Continuing from the previous post, lets develop a simple WebAPI REST app, running on cloud9.

So, create a new dotnet app to return the weather

dotnet new console -o theweather

Our api will just return the current weather

GET api/weather

  1. Add appsettings.json and appsettings.dev.json
  2. Add references for mvc6
  3. add startup class
  4. connect program to startup class

appsettings.json

{
   "Logging": {
     "IncludeScopes": false,
     "Debug": {
        "LogLevel": {
           "Default": "Warning"
        }
     },
     "Console": {
        "LogLevel": {
           "Default": "Warning"
        }
     }
   }
}

appsettings.development.json
{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
    "Default": "Debug",
  "System": "Information",
  "Microsoft": "Information"
  }
}
}

Controllers/WeatherController

Anyone who has used MVC/WebAPI in the past will see that nothing much has changed

  using System;
  using System.Linq;
  using Microsoft.AspNetCore.JsonPatch;
  using Microsoft.AspNetCore.Mvc;
  using System.Collections.Generic;</code>

  namespace theWeather.Controllers{

  [Route("api/[controller]")]
  public class WeatherController:Controller{

  [HttpGet]
  public IActionResult Get()
  {
    var CurrentWeather=new Weather{
     Forecast="Quite nice"
    };

    return Ok(CurrentWeather);
   }

 }

 public class Weather{
  public string Forecast{get;set;}
 }
}

theWeather.proj

&lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&gt;
  &lt;PropertyGroup&gt;
    &lt;OutputType&gt;Exe&lt;/OutputType&gt;
    &lt;TargetFramework&gt;netcoreapp2.0&lt;/TargetFramework&gt;
  &lt;/PropertyGroup&gt;

  &lt;ItemGroup&gt;
    &lt;PackageReference Include=&quot;Microsoft.AspNetCore.All&quot; Version=&quot;2.0.0&quot; /&gt;
  &lt;/ItemGroup&gt;

  &lt;ItemGroup&gt;
    &lt;DotNetCliToolReference Include=&quot;Microsoft.VisualStudio.Web.CodeGeneration.Tools&quot; Version=&quot;2.0.0&quot; /&gt;
  &lt;/ItemGroup&gt;

&lt;/Project&gt;

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;

namespace theWeather
{
    class Program
    {
        static void Main(string[] args)
        {
            SetupWebHost(args).Run();
        }
        
        public static IWebHost SetupWebHost(string[] args) =>
        
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<APIStartup>()
                .UseUrls("http://localhost:8080")
                .ConfigureAppConfiguration((context, config) =>
                {
                    var env = context.HostingEnvironment;

                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                           .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
                })
                .Build();
    }
}

APIStartup.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Serialization;

namespace theWeather{
    
    public class APIStartup{
        public IConfiguration Config { get; }

        
        public APIStartup(IConfiguration config){
             Config = config;
        }
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            
            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllOrigins",
                    builder =>
                    {
                        builder
                            .AllowAnyOrigin()
                            .AllowAnyHeader()
                            .AllowAnyMethod();
                    });
            });
            services.AddMvcCore()
                .AddJsonFormatters(options => options.ContractResolver = new CamelCasePropertyNamesContractResolver());
            
        }
        
         public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler(errorApp =>
                {
                    errorApp.Run(async context =>
                    {
                        context.Response.StatusCode = 500;
                        context.Response.ContentType = "text/plain";
                        var errorFeature = context.Features.Get<IExceptionHandlerFeature>();
                        if (errorFeature != null)
                        {
                            var logger = loggerFactory.CreateLogger("Global exception logger");
                            logger.LogError(500, errorFeature.Error, errorFeature.Error.Message);
                        }

                        await context.Response.WriteAsync("There was an error");
                    });
                });
            }

            app.UseCors("AllowAllOrigins");
            
            app.UseMvc();
        }
        
        
    }
}

Then run the dotnet program (no need to restore anymore)

dotnet run

Have fun, dotnetcore may seem very different, but really its only the packaging thats changed. If you have some npm or even nuget experience, it shouldn’t be that difficult to get on board.

Until next time, take care.