[译]初识.NET Core & ASP.NET Core

时间:2023-03-09 09:07:04
[译]初识.NET Core & ASP.NET Core

原文:点这

本文的源代码在此:

你过你是.NET Core的入门者,你可以先看看下面这篇文章:

命令行工具

我是在Windows上创建这个应用的,但是你可以在安装了.NET SDK的Mac或者Linux上面做同样的事情.

http://dot.net这下载.NET SDK. 下载并安装完.NET SDK后开始创建一个新项目于.

步骤如下:

  • 创建一个新文件夹
  • CD到这个文件夹下
  • 在命令行窗口运行dotnet new创建一个新项目
  • 运行dotnet restore下载必要的NuGet包
  • 运行dotnet run运行你的项目

可以看到我们只需要3步就完成了从创建到运行一个.NET应用的所有工作.

首先使用dotnet new创建一个项目,此时在项目文件夹下会有一个program.cs文件它包含一个public Main()方法, 就像其他的控制台程序一样.

然后你需要使用dotnet restore来下载项目所需的NuGet包. 空项目自己下载所需要的依赖包.

一旦你从NuGet下载完了所以依赖的包后使用dotnet run来运行你的项目:

[译]初识.NET Core & ASP.NET Core

现在你可以打开自动生成的program.cs文件,修改代码, 如下:

using System;

namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World. Time is: " +
DateTime.Now.ToString("t"));
}
}
}

回到命令窗口运行dotnet run你可以看到如下输出.

Hello World. Time is: 5:36 PM

注意当你运行dotnet run的时候会自动编译你的代码. 这里没有显性的编译步骤 - 当然你可以使用dotnet build来显性的编译项目.

回顾一下:

  • 安装.NET
  • 运行3个命令
  • 一些可运行的.NET代码

我的可执行程序在哪?

你可能注意到我们没有执行一个EXE文件, 我们只是在包含project.json的文件夹中执行了dotnet run, project.json文件中会告诉我们如何启动应用.

代码被编译放到了bin目录下的dll中.

ASP.NET是怎么样的呢?

ASP.NET Core是一个运行了Web server的控制台应用.

下面修改Main函数,让程序变成一个Web应用在浏览器上跑起来:

using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseStartup<Startup>()
.Build(); host.Run();
}
} public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.Run(async (context) =>
{
await context.Response.WriteAsync(
"Hello World. The Time is: " +
DateTime.Now.ToString("hh:mm:ss tt")); });
}
}
}

下面需要修改下project.json添加上Kestrel Web server和Http extensions:

"dependencies": {
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
},
"frameworks": { ... }

现在回到命令行运行

dotnet restore

获取依赖包,再运行

dotnet run

现在你应该能看到一个提示,Web服务器在5000端口上启动了. 在浏览器中打开http://localhost:5000,现在你应该可以看到来自于ASP.NET Core的问候了:

Hello World. The Time is: 6/3/2016 2:32:20 PM

可以看到一样的控制台应用结构被用来服务ASP.NET了.

Middleware

Main()中的代码使用了Kestrel,并对其进行了配置用来处理Web请求. 配置委托给了Startup类来处理,通常Startup应该放在一个单独的文件中.

Startup类中我们可以使用自定义的中间件来影响ASP.NET管道. Middleware本质上如同经典ASP.NET的HttpHandlerHttpModule.

App.Run()

上面的代码中Startup使用了App.Run()中间件.

App.Use - Middleware Modules

如果说App.Run()是个Http handler, 那么App.Use()就像个HttpModule. App.Use()可以串联起来按照指定的顺序来执行. 修改代码用来在每个请求的前后来执行一定的任务.

Configure方法的App.Run()前添加下面代码:

app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Pre Processing"); await next(); await context.Response.WriteAsync("Post Processing");
});

Ctrl-c停止服务后运行dotnet run重新运行程序,结果如下:

Pre Processing...Hello World. The Time is: 6/3/2016 3:10:19 PMPost Processing...

可以看到App.Use()的输出包裹住了App.Run()的输出. .

使用ASP.NET MVC

光向上面一样使用App.Use()App.Run()还达不到创建一个正式项目的程序.

当你创建一个Web应用的时候你需要使用更高级的东西比如ASP.NET MVC. 比起自己来实现中间件, ASP.NET MVC提供了丰富的中间件让你及其方便的来创建Web应用. 一旦配置好, 创建一个经典的ASP.NET Core MVC应用和之前你创建ASP.NET MVC应用一样简单.

下面我们在Startup中加入ASP.NET MVC,并创建一个简单的API用来返回JSON数据.

首先在project.json中添加下面的包:

  • "Microsoft.AspNetCore.Mvc": "1.0.0"

运行dotnet restore来现在依赖包.

修改Startup类:

using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseStartup<Startup>()
.Build(); host.Run();
}
} public class Startup
{ public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
} public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
}

上面的代码在ConfigureServices()中设置了所需的依赖注入,然后在Configure()中使用了MVC. 这是一个典型的模式: ConfigureServices()用来初始化依赖注入. Configure() then adjusts the behavior of the middleware which is typically a more specific wrapper around App.Use(). app.AddMvc()app.UseMvc()都是扩展方法,它们来自于Microsoft.AspNetCore.Mvc package.

在这个例子中MVC没用进行一些显性的配置, 但是其他的providers如EntityFrame或者Logging provider需要你配置一些连接字符串之类的.

下面来创建一个controller,代码如下:

public class HelloWorldController
{
[HttpGet("api/helloworld")]
public object HelloWorld()
{
return new
{
message = "Hello World",
time = DateTime.Now
};
}
}

这个controller有一个可以返回匿名对象数据的API端点. 因为是一个API所以它的结果会被序列化 - 通常是一个JSON格式 (依赖于客户端浏览器的accept header).

现在回到命令行运行dotnet run. 打开http://localhost:5000/api/helloworld.

可以看到下面的结果:

{
message: "Hello World",
time: "2016-06-03T15:39:18.339626-07:00"
}

POCO Controller

注意上面的controller并没有继承Controller类. ASP.NET Core会知道HelloWorldController是一个Controller,因为他的后缀是Controller. 除非你需要使用Controller的一些特性,不然你不需要继承Controller.

添加Razor视图

接下来在controller中添加另外一个方法来展示Helloworld视图. 首先我们需要添加一些package. project.json添加下面的内容:

  • "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0"

运行dotnet restore, 然后在Main()中使用.UseContentRoot()用来提供应用的根路径

public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.UseStartup<Startup>()
.Build();
host.Run();
}

UseContentRoot是必须要的!

现在在Helloworld控制器中添加一个方法. 注意在ASP.NET Core MVC中支持在一个controller中同时使用API和MVC端点, 因此在这我不需要另外再创建一个controller:

[HttpGet("helloworld")]
public ActionResult HelloworldMvc()
{
ViewBag.Message = "Hello world!";
ViewBag.Time = DateTime.Now; return View("helloworld");
//return View("~/helloworld.cshtml");
}

注意了在我们的controller是用来处理API请求的时候,controller没有继承自Controller. 但在这我们需要让我们的controller继承Controller,因为在这我们使用了ViewBagView,他们都是Controller的成员.

让我们的controller继承自Controller:

public class HelloworldController : Controller

/Views/Helloworld文件夹下创建helloworld.cshtml.

视图的代码非常简单,如下:

<label>Message:</label>
@ViewBag.Message <hr/> <label>Time:</label>
@ViewBag.Time

现在你需要在project .jsonbuildoption section中添加如下配置:

  • "preserveCompilationContext": true

    如果你用了动态的视图这个配置是必须的.

现在回到命令行再次运行dotnet run 在浏览器中打开http://localhost:5000/helloworld

可以看到如下页面:

Message: Hello world!
---
Time: 6/3/2016 9:29:12 PM

所有的代码如下:

using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http; namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseKestrel()
.UseStartup<Startup>()
.Build(); host.Run();
}
} public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
} public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage(); app.UseMvc(); //app.Use(async (context, next) =>
//{
// await context.Response.WriteAsync("Pre Processing");
// await next();
// await context.Response.WriteAsync("Post Processing");
//}); // Handler of last Resort
app.Run(async (context) =>
{
await context.Response.WriteAsync(
"Hello World of the last resort. The Time is: " +
DateTime.Now.ToString("hh:mm:ss tt")); });
}
} public class HelloWorldController : Controller
{
[HttpGet("api/helloworld")]
public object HelloWorld()
{
return new
{
message = "Hello World",
time = DateTime.Now
};
} [HttpGet("helloworld")]
public ActionResult HelloworldMvc()
{
ViewBag.Message = "Hello world!";
ViewBag.Time = DateTime.Now; return View("helloworld");
//return View("~/helloworld.cshtml");
}
}
}

IIS去哪了?

到现在为止我们只是在Windows上运行了一个控制台应用, 没有使用诸如IIS之类的WEB服务器来托管我们的应用. 因为ASP.NET Core使用了一个自托管的WEB服务器(Kestrel它是一个ASP.NET Core的高性能WEB服务器 which ASP.NET Core’s high performance Web Server).

但是,并不推荐在Internet中直接通过Kestrel来访问我们的应用. 你应该使用一个前端的反向代理,例如Windows上的IIS,Linux上面的Nginx.

Running on a Mac

到目前为止我们一直是在Windows机器上来运行程序的, 但上面的代码可以不经任何修改的搬到Mac上运行!


PS: 第一次使用Markdown编辑文章,挺好。