天天看點

.NET跨平台:在Mac上跟着錯誤資訊一步一步手寫ASP.NET 5程式

今天坐高鐵時嘗試了一種學習ASP.NET 5的笨方法,從空檔案夾開始,根據運作dnx . kestrel指令的錯誤資訊,一步一步寫代碼,直至将一個最簡單的ASP.NET程式運作起來。雖然是用最笨的方法寫了一個最簡單的程式,但是這麼動手操作一次,感覺就是不一樣。

今天坐高鐵時嘗試了一種學習ASP.NET 5的笨方法,從空檔案夾開始,根據運作dnx . kestrel指令的錯誤資訊,一步一步寫代碼,直至将一個最簡單的ASP.NET程式運作起來。

嘗試的具體步驟如下。

建立一個空檔案夾HelloCnblogs:

mkdir HelloCnblogs && cd $_      

在這個空HelloCnblogs檔案夾中運作 dnx . kestrel 指令(基于CoreCLR的dnx),運作結果是如下的出錯資訊: 

System.InvalidOperationException: Unable to resolve project 'HelloCnblogs' from /Git/HelloCnblogs
   at Microsoft.Framework.Runtime.ApplicationHostContext..ctor
...      

添加一個空project.json檔案(指令為touch project.json),運作dnx . kestrel指令,錯誤資訊如下:

Error: Microsoft.Framework.Runtime.FileFormatException: 
The JSON file can't be deserialized to a JSON object. 
   at Microsoft.Framework.Runtime.Project.GetProjectFromStream(
   Stream stream, String projectName, String projectPath, ICollection`1 diagnostics)      

在project.json檔案中添加 {} ,運作dnx . kestrel指令,錯誤資訊如下:

System.InvalidOperationException: Unable to load application or execute command 'kestrel'.
at Microsoft.Framework.ApplicationHost.Program.ThrowEntryPointNotfoundException(
DefaultHost host, String applicationName, Exception innerException)      

在project.json中添加kestrel command:

"commands": {
    "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:8080"
}      

運作dnx . kestrel,出錯資訊如下:

System.InvalidOperationException: Unable to load application or execute command 'Microsoft.AspNet.Hosting'. 
Available commands: kestrel.
   at Microsoft.Framework.ApplicationHost.Program.ThrowEntryPointNotfoundException(
   DefaultHost host, String applicationName, Exception innerException)      

在project.json中添加對Kestrel的引用

"dependencies": {
	"Kestrel": "1.0.0-*"
}      

運作dnu restore之後(基于mono的dnu),再運作dnx . kestrel,出錯資訊變為:

System.InvalidOperationException: 
Failed to resolve the following dependencies for target framework 'DNXCore,Version=v5.0':
   Kestrel 1.0.0-beta6-11871      

在project.json中添加frameworks:

"frameworks": {
     "dnxcore50": { }
}      

運作dnu restore && dnx . kestrel,出現錯誤:

System.InvalidOperationException: A type named 'StartupProduction' or 'Startup' could not be found in assembly 'HelloCnblogs'.
at Microsoft.AspNet.Hosting.Startup.StartupLoader.FindStartupType(String startupAssemblyName, IList`1 diagnosticMessages)      

建立Startup.cs檔案,并添加一個Startup類:

namespace HelloCnblogs
{
    public class Startup
    {        
    }
}      

繼續dnx . kestrel,出現錯誤:

System.InvalidOperationException: 
A method named 'ConfigureProduction' or 'Configure' in the type 'HelloCnblogs.Startup' could not be found.
   at Microsoft.AspNet.Hosting.Startup.StartupLoader.FindMethod(
   Type startupType, String methodName, String environmentName, Type returnType, Boolean required)      

給Startup類添加Configure方法:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
    }    
}      
error CS0246: The type or namespace name 'IApplicationBuilder' could not be found (are you missing a using directive or an assembly reference?)      

在Startup.cs中添加命名空間:

using Microsoft.AspNet.Builder;      

繼續dnx . kestrel,這次成功運作!

Started      

這裡用浏覽器通路 http://localhost:8080/ ,能成功通路,但頁面一片空白,因為我們在程式中沒進行任何内容輸出操作。

于是,在Startup.cs中添加輸入内容的代碼:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async context => await context.Response.WriteAsync("Hello, cnblogs!"));
    }    
}      

繼續用dnx . kestrel指令運作,出現錯誤:

error CS1061: 'HttpResponse' does not contain a definition for 'WriteAsync' and no extension method 'WriteAsync' accepting a first argument of type 'HttpResponse' could be found (are you missing a using directive or an assembly reference?)      
using Microsoft.AspNet.Http;      

再次運作,成功!

$ dnx . kestrel
Started      

浏覽器通路 http://localhost:8080/ ,得到正常的響應内容:

Hello, cnblogs!      

通過這樣的試錯法,得到了運作一個最簡單的ASP.NET 5程式的最小配置:

一個檔案夾,2個檔案(project.json與Startup.cs)。

project.json檔案中的内容:

{
    "commands": {
        "kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:8080"
    },
    "dependencies": {
        "Kestrel": "1.0.0-*"
    },
    "frameworks": {
         "dnxcore50": { }
    }
}      

Startup.cs中的内容:

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;

namespace HelloCnblogs
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.Run(async context => await context.Response.WriteAsync("Hello, cnblogs!"));
        }    
    }
}      

雖然是用最笨的方法寫了一個最簡單的程式,但是這麼動手操作一次,感覺就是不一樣。

繼續閱讀