Asp.Net Core is a toolset for creating web applications for .Net Core. Although the name contains ASP.Net this is an absolutely new product for web-developers.
It is simple and clear and it allows you to write more compact code. Web applications created with Asp.Net Core are cross platform and can be ran without IIS (Internet Information Server) and Azure (but can work with them too).
Lets stop talking and create a simple ASP.Net Core application without from scratch. We will not use any code generators (like yeoman) nor any IDE. No ugly web.config files. Even Windows is not required (but can be used). Only terminal and your favorite text editor. .Net Core SDK should be pre-installed too of cause.
Create new .Net Core console application in empty directory by command
dotnet new -T Console
Open the created file project.json
and add to field dependencies
next values:
In project.json
{
"Microsoft.NETCore.App": {
"version": "1.0.0",
"type": "platform"
},
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
}
The first line will add Asp.Net Core support to our application. The second line will allow the web application to be self-hosted (with Kestrel web server).
From Command line Run:
dotnet restore
That will install ASP.Net core packages.
Copy/Paste into Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel() // use self-hosted web server
.UseStartup()
.Build();
host.Run();
}
}
public class Startup
{
public void Configure()
{
}
}
}
From Command line Run:
dotnet run
Hooray, we did it! Open browser to: http://localhost:5000 and see … nothing.
Let’s make our web application show some text.
Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
namespace ConsoleApplication
{
public class Program { /* unchanged */ }
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// We'll add own middleware
app.Use(async (context, next) => {
await next.Invoke(); // call other chained middlewares
await context.Response.WriteAsync("Hello ASP.Net Core");
});
// If you work with express or koa in nodejs or sinatra in ruby you will see a lot of similar stuffs here
}
}
}
Run the application again. Good. Now we can see text “Hello ASP.Net Core” in the browser.
MVC
Let’s make our application more complex. First add MVC support. Open project.json
and add into dependencies
line
"Microsoft.AspNetCore.Mvc": "1.0.0"
Run
dotnet restore
to install ASP.Net MVC libraries.
Now change class Startup
public void ConfigureServices(IServiceCollection services)
{
// This method is used to register services to use them via Dependency Injection in other parts of code.
services.AddMvc();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
Now our application is MVC-powered.
Lets create a controller. Create directory controllers
and add file DemoController.cs
there with content
DemoController.cs
using Microsoft.AspNetCore.Mvc;
namespace ConsoleApplication.Controllers
{
[Route("[controller]")]
public class DemoController : Controller
{
// GET /demo
[HttpGet]
public string Index()
{
return "Hello ASP.Net Core";
}
}
}
Attribute [Route("[controller]")]
says that our controller will handle routes with pathes /demo
(demo
is taken from name of DemoController
).
Lets run our application and make GET request to http://localhost:5000/demo
. We will see text “Hello ASP.Net Core”.
Let’s make this action a bit more async.
In DemoController.cs
// GET /demo
[HttpGet]
public async Task Index()
{
// call any async methods with `await` here
return Task.FromResult("Hello ASP.Net Core");
}
Ok, let’s make action which can extract query parameters from request. Add next method to DemoController
.
In DemoController.cs
// GET /demo/query
[HttpGet("query")]
public string Query([FromQuery] string text)
{
return $"Your query string is "{text}"";
}
Run the application and make GET request to http://localhost:5000/demo/query?text=hello
to see result. Replace [FromQuery]
by [FromQuery(Name="q")]
. Now our application will handle GET requests like http://localhost:5000/demo/query?q=hello
.
Lets extract parameter from request url. Add next method
In DemoController.cs
// GET /demo/{id}
[HttpGet("{id}")]
public string Get(string id)
{
return $"Item {id}";
}
Now we can make GET requests like /demo/123
.
What about posting form data? Lets add this method.
In DemoController.cs
// POST /demo
[HttpPost]
public IActionResult Create([FromForm] Item item)
{
return Created("http://localhost/demo/id", item);
}
where Item
is
public class Item
{
public string Text {get; set;}
}
Re-run the application and make POST request to /demo
with form (application/x-www-form-urlencoded
) text=hello
. If you omit field text
in such request the property Text
of item
in method Create()
will be null
.
Lets handle json data. Replace [FromForm]
in method Create
by [FromBody]
. Now make POST request to /demo
with json content {"Text": "hello"}
You will see same result.
But if we post in json field text
instead of Text
the item.Text
will be null
. Lets fix that. Open Program.cs
and change ConfigureServices
of StartUp
by
In Program.cs
services
.AddMvc()
.AddJsonOptions(s => s.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());
Now our app will work with camel-cased names in json data right.
Dependency injection
Dependency injection is a technique for achieving loose coupling between objects and their collaborators, or dependencies. Rather than directly instantiating collaborators, or using static references. The objects a class needs in order to perform its actions are provided to the class in some fashion. ASP.Net Core has support of dependency injection in the box. Lets see how it works.
Lets add a “useful” service
public interface IMyUsefullService{
void Run();
}
public class MyUsefullService : IMyUsefullService
{
public void Run()
{
//TODO do something
}
}
Now register our service in ConfigureServices
of Startup
by line
services.AddTransient<IMyUsefullService, MyUsefullService>();
Thats all. Now we can use instance of IMyUsefullService
in constructor of any our controller and instance of MyUsefullService
will be used there.
public class DemoController : Controller
{
private readonly IMyUsefullService _myUsefullService;
// Constructor
public DemoController (IMyUsefullService myUsefullService)
{
if(myUsefullService == null)
{
throw new ArgumentNullException(nameof(myUsefullService));
}
_myUsefullService = myUsefullService;
// now we can use _myUsefullService in any action of this controller
// instance of MyUsefullService will be stored in this field but the controller doesn't know about that
}
}
Here we showed a small piece of ASP.Net Core infrastructure. The basis of any ASP.Net Core application is small kernel which includes middleware, dependency injection, logging, configuration, and error handling support. Other possibilities (like MVC, Views, Databases, etc supports) are implemented as external libraries.
You can use only things you explicitly require. Each such library extends web application by new middlewares (their registering code is often hidden in extension methods of IApplicationBuilder
) and services (like database context). You can split your own code to middlewares and share it with different applications.
Say hello to more compact and clear code of web applications in .Net Core universe. Start to use ASP.Net Core in new projects.