微软的东西越来越棒了,各种开源和跨平台工具相继推出。.NET Core终于让.NET开始像Java一样,可以在任意平台上运行代码。最近学习了下微软的教程,结合跨平台的Dynamic Web TWAIN,分享下我的第一个ASP.NET Core "Hello World"。
安装
Hello World
如何初始化一个ASP.NET Core的工程?根据微软的教程:
mkdir aspnetcoreapp
cd aspnetcoreapp
dotnet new -t web
创建的工程包含了很多的文件,已经比较复杂了。要搞明白发生了什么,还是一步一步创建文件比较好。所以只需要用命令:
dotnet new
这样会创建一个命令行工程,包含两个文件Program.cs和project.json。我需要的是web server,所以修改下这两个文件。
Program.cs:
using System.IO;
using aspnetcoreapp;
using Microsoft.AspNetCore.Hosting;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.Build();
host.Run();
}
}
}
project.json:
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.AspNetCore.StaticFiles": "1.0.0"
},
"imports": "dnxcore50"
}
}
}
这里做的事情就是添加了web server Kestrel,以及通过当前路径加载静态文静。还需要创建一个Startup.cs:
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
namespace aspnetcoreapp
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// app.UseDefaultFiles();
// app.UseStaticFiles();
app.UseFileServer();
}
}
}
UseFileServer等同与UseDefaultFiles+UseStaticFiles。默认加载wwwroot目录下的静态文件,并把index.html当作首页。当然你可以通过代码去修改路径。如果现在部署静态html文件,已经可以访问了。
为了让server端做一点事情,做一个文件上传功能。首先需要映射一下路径,比如上传的url是www.xxx.com/upload。打开index.html做一下修改:
var strActionPage = CurrentPath + "upload";
一旦满足条件就可以执行操作:
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
namespace aspnetcoreapp
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
// app.UseDefaultFiles();
// app.UseStaticFiles();
app.UseFileServer();
app.Map("/upload", UploadFile);
}
private static void UploadFile(IApplicationBuilder app)
{
app.Run(async context =>
{
var files = context.Request.Form.Files;
var uploads = Path.Combine(Directory.GetCurrentDirectory(), "uploads");
if (!Directory.Exists(uploads)) {
Directory.CreateDirectory(uploads);
}
foreach (var file in files)
{
var filename = file.FileName;
using (var fileStream = new FileStream(Path.Combine(uploads, filename), FileMode.Create))
{
await file.CopyToAsync(fileStream);
}
}
});
}
}
}
现在可以运行下程序:
dotnet restore
dotnet run
浏览器中打开localhost:5000看到的效果:
MVC
现在用MVC来改造下上面的代码。首先在project.json中添加新的依赖:
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
},
"Microsoft.AspNetCore.Mvc": "1.0.1",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
"Microsoft.AspNetCore.StaticFiles": "1.0.0"
},
"imports": "dnxcore50"
}
},
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
}
}
在Startup.cs中添加MVC服务:
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace aspnetcoreapp
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
}
}
MVC中使用了路径模版。默认情况下需要一个HomeController.cs:
using Microsoft.AspNetCore.Mvc;
namespace aspnetcoreapp.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
这个文件放在Controller目录下。对应的还有一个Index.cshtml文件,放在Views/Home目录下。把之前的那个index.html改一下名就可以了。
因为上传的URL是www.xxx.com/upload,相对的也要创建一个Controller/UploadController.cs:
using Microsoft.AspNetCore.Mvc;
using System.IO;
namespace aspnetcoreapp.Controllers
{
public class UploadController : Controller
{
[HttpPost]
public void Index()
{
var files = Request.Form.Files;
var uploads = Path.Combine(Directory.GetCurrentDirectory(), "uploads");
if (!Directory.Exists(uploads))
{
Directory.CreateDirectory(uploads);
}
foreach (var file in files)
{
var filename = file.FileName;
using (var fileStream = new FileStream(Path.Combine(uploads, filename), FileMode.Create))
{
file.CopyTo(fileStream);
fileStream.Flush();
}
}
}
}
}
这样就完成了。