[2017 Study4TW .NET Conf] ASP.NET Core 實務實戰教學 - 網頁開發範例與 windows 服務

熱門文章 (Popular Post)

Posted by : Duran Hsieh 10月 21, 2017

前言

本篇內容為 2017 Study4TW .NET Conf  - ASP.NET Core 實務實戰教學 -  網頁開發範例,所有開發範例,希望與會者能透過一步步的操作,ASP.NET Core網頁開發有更進一步的了解。本篇文章若有錯誤或任何建議,希望各位先進不吝指出,謝謝。


其他課程資源請參考:http://study4.tw/Activity/Details/9



目錄

範例 1. First ASP.NET Core Project
範例 2. Self-contained deployment with URL
範例 3. Configuration
範例 4. Dependency injection
範例 5. Razor Page

範例 6. Windows Services
範例下載



範例

範例 1. First ASP.NET Core Project

Step 1. 檔案 → 新增專案 → Visual C# → ASP.NET Core Web 應用程式

Step 2. 選擇 Web 應用程式(模型-檢視-控制器)

Step 3.1 右鍵點選專案 → 建立 ViewModels 資料夾 
Step 3.2 ViewModels資料夾點右鍵 → 新增 → 新增項目 → 類別 → StudentModel.cs
貼上以下程式碼
 
using System;

namespace AspDotNetCoreExample.ViewModels
{
    public class StudentModel
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }
    }
}


Step 4.1 右鍵點選專案 → 建立 Serivces 資料夾
Step 4.2 右鍵點選Serivces資料夾 → 建立 Queries 資料夾
Step 4.3 右鍵點選Serivces資料夾 → 建立 Commands資料夾

Step 5.1 資料夾點右鍵 → 新增 → 新增項目 → 類別 → StudentQueries.cs
Step 5.2 貼下以下程式碼
 

using AspDotNetCoreExample.ViewModels;
using System;
using System.Collections.Generic;

namespace AspDotNetCoreExample.Services.Commands
{
    public class StudentQueries
    {
        public StudentModel GetStudentById(int studentId)
        {
            return new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Duran"
            };
        }

        public List<StudentModel> GetStudents()
        {
            List<StudentModel> list = new List<StudentModel>();
            list.Add(new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Duran"
            });

            list.Add(new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Sky"
            });

            list.Add(new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Kyle"
            });

            return list;
        }
    }
}

Step 5.3 資料夾點右鍵 → 新增 → 新增項目 → 類別 → StudentCommands.cs
Step 5.4 貼上以下程式碼
 
using AspDotNetCoreExample.ViewModels;
using System;

namespace AspDotNetCoreExample.Services.Commands
{
    public class StudentCommands
    {
        public bool CreateStudent(StudentModel model)
        {
            return true;
        }

        public bool UpdateStudent(StudentModel model)
        {
            return true;
        }

        public bool DeleteStudentById(Guid id)
        {
            return true;
        }
    }
}

你的Services資料夾會長得像這樣:

Step 6. 右鍵點選Controllers資料夾新增 Controller(空白) → 名稱為 StudentController
貼上下列程式碼
 
using Microsoft.AspNetCore.Mvc;
using AspDotNetCoreExample.Services.Commands;

namespace AspDotNetCoreExample.Controllers
{
    public class StudentController : Controller
    {
        public StudentQueries query = new StudentQueries();

        public IActionResult Index()
        {
            var result = query.GetStudents();
            return View(result);
        }

        public IActionResult Detail(int studentId)
        {
            var result = query.GetStudentById(studentId);
            return View(result);
        }
    }
}


Step 7.1 滑鼠移到 StudentController.cs 內 Index 內 → 點選右鍵 → 新增檢視  → 點選確定

Step 7.2 貼下以下程式碼
 
@using AspDotNetCoreExample.ViewModels
@model List<StudentModel>

@foreach(var item in Model)
{
    <div>
        <p>
            <a href="@Url.Action("Detail","Student", new { id = 10 })">
                @item.Name
            </a>
        </p>
        <p>年齡:@item.Age </p>
    </div>
}

Step 8.1 滑鼠移到 StudentController.cs 內 Detail 內 → 點選右鍵 → 新增檢視 
 
@using AspDotNetCoreExample.ViewModels
@model StudentModel

<div>
    <p>姓名:@Model.Name </p>
    <p>年齡:@Model.Age </p>
</div>


Step 9 啟動專案,輸入網址 http://localhost:xxxx/student/






範例 2. Self-contained deployment with URL

Step 1. 對專案點右鍵 → 編輯 xxx.csproj檔案

Step 2. 在     內貼上
 
win10-x64;osx.10.11-x64


Step 3. 右鍵點選專案 → 選擇發行

Step 4.1 開啟發布資料夾,點選exe 檔案
Step 4.2 開啟瀏覽器開啟 http://localhost:5000

如果你需要指定網址,可以在Program.cs 加上
.UseUrls("http://*:5000;http://www.xxx.com;https://10.xxx.3.114")




範例 3. Configuration

Step 1. 開啟startup.cs,將下列程式碼進行替換
 
public Startup(IConfiguration configuration)
{
     Configuration = configuration;
}


 
public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
        
    Configuration = builder.Build();
}

Step. 2 在 appsetting.json 內貼上下列程式碼
 
{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "EmailConfig":{
    "SMTP": "test.smtp.com",
    "Port": 25
  }
}


Step 3.1  建立BaseModel 資料夾,資料夾點右鍵 → 新增 → 新增項目 → 類別 → EmailConfig.cs
Step 3.2 貼上以下程式碼
namespace AspDotNetCoreExample.BaseModel
{
    public class EmailConfig
    {
        public string SMTP { get; set; }

        public int Port { get; set; }
    }
}


Step 4. 在Startup.cs 內ConfigureServices 方法貼上
 
services.Configure<EmailConfig>(Configuration.GetSection("EmailConfig"));


Step 5. HomeController.cs 內貼上
 

 private EmailConfig _emailConfig = null;

        public HomeController(IOptions<EmailConfig> emailConfig)
        {
            _emailConfig = emailConfig.Value;
        }

Step 6. 在 HomeController.cs,About 方法內貼上
 
ViewData["SMTP"] = _emailConfig.SMTP;

Step 7. 在Views\Home\About.cshtml 內貼上
 

@ViewData["SMTP"]


Step 8. 執行專案觀看結果

Step. 9 在 appsetting.Development.json 內貼上下列程式碼
 
{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  },
  "EmailConfig": {
    "SMTP": "development.smtp.com",
    "Port": 25
  }
}

Step.10 右鍵點選專案 → 屬性 → 偵錯 確認環境變數內容為
Step 11. 執行專案觀看結果





範例 4. Dependency injection 

Step 1.1 右鍵點選專案 → 加入→ 新資料夾 Interfaces
Step 1.2 右鍵點選資料夾 Interfaces → 加入 →新增項目 →介面 IStudentQueries.cs
Step 1.3 貼上以下程式碼
 
using AspDotNetCoreExample.ViewModels;
using System.Collections.Generic;

namespace AspDotNetCoreExample.Interface
{
    public interface IStudentQueries
    {
        StudentModel GetStudentById(int studentId);

        List<StudentModel> GetStudents();
    }
}

Step 1.4 右鍵點選資料夾 Interfaces → 加入 →新增項目 →介面 IStudentCommands.cs
Step 1.5 貼上以下程式碼
 
using AspDotNetCoreExample.ViewModels;
using System;

namespace AspDotNetCoreExample.Interface
{
    public interface IStudentCommands
    {
        bool CreateStudent(StudentModel model);

        bool UpdateStudent(StudentModel model);

        bool DeleteStudentById(Guid id);
    }
}

你的專案會長得像這樣:
Step 2.1 修改你的 Services\Queries\StudentQueries.cs 如下
 

using AspDotNetCoreExample.Interface;
using AspDotNetCoreExample.ViewModels;
using System;
using System.Collections.Generic;

namespace AspDotNetCoreExample.Services.Commands
{
    public class StudentQueries : IStudentQueries
    {
        public StudentModel GetStudentById(int studentId)
        {
            return new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Duran"
            };
        }

        public List<StudentModel> GetStudents()
        {
            List<StudentModel> list = new List<StudentModel>();
            list.Add(new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Duran"
            });

            list.Add(new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Sky"
            });

            list.Add(new StudentModel
            {
                Id = Guid.NewGuid(),
                Age = 18,
                Name = "Kyle"
            });

            return list;
        }
    }
}

Step 2.2 改你的 Services\Commands\StudentCommands.cs 如下
 

using AspDotNetCoreExample.Interface;
using AspDotNetCoreExample.ViewModels;
using System;

namespace AspDotNetCoreExample.Services.Commands
{
    public class StudentCommands : IStudentCommands
    {
        public bool CreateStudent(StudentModel model)
        {
            return true;
        }

        public bool UpdateStudent(StudentModel model)
        {
            return true;
        }

        public bool DeleteStudentById(Guid id)
        {
            return true;
        }
    }
}


Step 3.1  修改你的 Controllers\StudentController.cs 如下
 

using Microsoft.AspNetCore.Mvc;
using AspDotNetCoreExample.Services.Commands;
using AspDotNetCoreExample.Interface;

namespace AspDotNetCoreExample.Controllers
{
    public class StudentController : Controller
    {
        private IStudentQueries _studentQueries;

        public StudentController(IStudentQueries studentQueries)
        {
            _studentQueries = studentQueries;
        }

        public IActionResult Index()
        {
            var result = _studentQueries.GetStudents();
            return View(result);
        }

        public IActionResult Detail(int studentId)
        {
            var result = _studentQueries.GetStudentById(studentId);
            return View(result);
        }
    }
}

Step 4 在你的 Startup.cs 內ConfigureServices加入程式如下
 
services.AddTransient<IStudentQueries, StudentQueries>();
services.AddTransient<IStudentCommands, StudentCommands>();

Step 5 執行專案





範例 5. Razor Page

Step 1. 新增專案 →  ASP.NET Core Web 應用程式 → Web 應用程式

Step 2.1 右鍵點選專案 → 新增資料夾 Models
Step 2.2 右鍵點選資料夾 Models → 加入 → 新增項目 → 類別StudentModel.cs
Step 2.3 貼上程式如下:
 
using System;

namespace RazorPage.Models
{
    public class StudentModel
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }
    }
}

你的專案會像下圖

Step 3.1 右鍵點選 Pages → 加入 → Razor 頁面 Create.cshtml

Step 4 Create.cshtml.cs 加入以下程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RazorPage.Models;

namespace RazorPage.Pages
{
    public class CreateModel : PageModel
    {

        [BindProperty]
        public StudentModel Student { get; set; }

        public string GetMessage { get; set; }
        public string PostMessage { get; set; }

        public async Task OnGetAsync()
        {
            GetMessage = "GET";
        }

        public async Task<IActionResult> OnPostAsync()
        {
            PostMessage = Student.Name;
            return Page();
        }
    }
}

Step 5 Create.cshtml 加入以下程式碼
 
@page
@model RazorPage.Pages.CreateModel
@{
    ViewData["Title"] = "Create";
}

<h2>Create</h2>
<p>
    GetMessage: @Model.GetMessage
</p>
<p>
    PostMessge:@Model.PostMessage
</p>
<p> 
    Enter your name.
</p>
<div asp-validation-summary="All"></div>
<form method="POST">
    <div>Name: <input asp-for="Student.Name" /></div>
    <input type="submit" />
</form>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Step 6. 執行專案 開啟瀏覽器輸入 http://localhost:xxxxx/create





範例 6. Windows Services

建立 ASP.NET Core Web 應用程式(.Net Framework) 
1. 開啟 Visual Studio Community 2017 -> 檔案 -> 新增 ->專案

2. 選擇ASP.NET Core Web 應用程式 

Step 3. 我們選擇 Web API 範本(.NET Framework),點選確定完成專案建立

透過 Nuget 安裝 Microsoft.AspNetCore.Hosting.WindowsServices
Step 1. 我們選擇 工具 -> NuGet封裝管理員 -> 管理方案的 Nuget 套件

Step 2. 於瀏覽輸入 Microsoft.AspNetCore.Hosting.WindowsServices 搜尋並進行安裝


修改應用程式執行路徑與執行方式
我們需要稍微修改一下 ASP.NET Core Web 應用程式:
1. 應用程式取得靜態資料夾位址的方法為 Directory.GetCurrentDirectory();但若是建構 Windows Services,我們取得位置為該服務執行的資料夾。
2. 原先我們需要透過 host.Run() 啟動我們的應用程式;但若是建構 Windows Services,我們執行的方法為 host.RunAsService()。
 
using System.IO;
using Microsoft.AspNetCore.Hosting;
using System.Diagnostics;
using Microsoft.AspNetCore.Hosting.WindowsServices;

namespace WindowsServices
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            var pathToContentRoot = Path.GetDirectoryName(pathToExe);
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(pathToContentRoot)
                .UseIISIntegration()
                .UseStartup()
                .Build();

            host.RunAsService();
        }
    }
}


發佈專案至資料夾
Step 1.對專案點選右鍵 -> 發行

Step 2.選擇資料夾,我們將路徑更改為 C:\WindowsServicExample,選擇發行

Step 3. 於資料夾可以看見發行程式內容


SC 指令建立 windows service
我們能透過 SC 指令建立、開始、停止予刪除服務,語法如下:
 
sc create MyService binPath="C:\WindowsServiceExample\AspNetCoreWindowsServices.exe"
sc start MyService
sc stop MyService
sc delete MyService
MyService 為服務名稱,可自行命名,binPath為程式所在位置。
Step 1.我們先建立與啟動服務

Step 2.開啟服務檢視MyService

Step 3.開啟網頁,輸入http://localhost:5000/api/values,可以看見 WebAPI 正常啟動

若需要重新安裝服務,可以透過 stop與 delete 指令移除服務


除錯與測試
當我們在開發windows services 必須不斷重新安裝、啟動,工作相當繁複,對於除錯、測試與讀取 log 相當不方便。我們其實先轉回開發 console app 方式進行開發,待告一段落後再註冊服務進行實際測試。下面參考官方網站改寫program.cs,讓您於開發期間以 console app方式啟動,而發佈後以windows service 方式執行。
 
using System.IO;
using Microsoft.AspNetCore.Hosting;
using System.Diagnostics;
using Microsoft.AspNetCore.Hosting.WindowsServices;
using System.Linq;

namespace WindowsServices
{
    public class Program
    {
        public static void Main(string[] args)
        {
            bool isService = true;
            if (Debugger.IsAttached || args.Contains("--console"))
            {
                isService = false;
            }
            var pathToContentRoot = Directory.GetCurrentDirectory();
            if (isService)
            {
                var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
                pathToContentRoot = Path.GetDirectoryName(pathToExe);
            }


            var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(pathToContentRoot)
            .UseIISIntegration()
            .UseStartup()
            .Build();
            if (isService)
            {

                host.RunAsService();
            }
            else
            {
                host.Run();
            }
        }
    }
}

範例下載:

https://github.com/matsurigoto/AspDotNetCoreExample


Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Duran Hsieh @ Matsurigoto - Date A Live - Powered by Blogger - Designed by Johanes Djogan -