"ASP.NET Core micro-service real" - reading notes (Chapter 7)

Chapter 7 develop ASP.NET Core Web Application

ASP.NET Core basis

In the case of this chapter, we will start a command-line application, and without the aid of any templates, scaffolding and wizards, and ultimately get a fully functional Web application

GitHub link: https://github.com/microservices-aspnetcore/hello-world

After running dotnet new console command, we first get a Program.cs file, modify the configuration file and add support

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;

namespace StatlerWaldorfCorp.HelloWorld
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var config = new ConfigurationBuilder()
                .AddCommandLine(args)
                .Build();

            var host = new WebHostBuilder()
                .UseKestrel()
                .UseStartup<Startup>()
                .UseConfiguration(config)
                .Build();

            host.Run();            
        }
    }
}

After adding a Startup class, is used to configure the default middleware, it all HTTP requests return "Hello World" response

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;

namespace StatlerWaldorfCorp.HelloWorld {
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello, world!\n");
            });
        }
    }
}

Add NuGet package as a dependency of the project and direct the project in a statement at the beginning of the file you want to use Web SDK

<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>    
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="1.1.1"/>
    <PackageReference Include="Microsoft.Extensions.Logging" Version="1.1.1"/>
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1"/>
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1"/>
    <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="1.1.1"/>
 </ItemGroup>

</Project>

Add ASP.NET MVC middleware

GitHub link: https://github.com/microservices-aspnetcore/webapp

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;

namespace StatlerWaldorfCorp.WebApp
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {

        }

        public IConfiguration Configuration { get; set; }

        public void ConfigureServices(IServiceCollection services) {            
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {     
           app.UseMvc(routes =>
           {
               routes.MapRoute("default",
                   template: "{controller=Home}/{action=Index}/{id?}");
           });
        }
    }
}

To make this work, we also need to add NuGet package dependencies: Microsoft.AspNetCore.Mvc

Add Controller

The controller responsible for:

  • (1) receives an input from the HTTP request
  • (2) Input to the service class to process HTTP communication, JSON independent parse
  • (3) returns the appropriate response code and text
using Microsoft.AspNetCore.Mvc;
namespace StatlerWaldorfCorp.WebApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return "Hello World";            
        }
    }
}

Just add the contents of the above documents, the route had created this controller can automatically detect and let it take effect

Adding model

We created a simple model used to represent the stock quote

namespace StatlerWaldorfCorp.WebApp.Models
{
    public class StockQuote
    {
        public string Symbol { get; set; }
        public int Price { get; set; }
    }
}

Add View

<html>
<head>
    <title>Hello world</title>
</head>
<body>
    <h1>Hello World</h1>
    <div>
        <h2>Stock Quote</h2>
        <div>
            Symbol: @Model.Symbol<br/>
            Price: [email protected]<br/>
        </div>
    </div>
</body>
</html>

Now, we can use to modify HomeController, not to return to sample text, but to render the view

using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using StatlerWaldorfCorp.WebApp.Models;

namespace StatlerWaldorfCorp.WebApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            var model = new StockQuote { Symbol = "HLLO", Price = 3200 };

            return View(model);            
        }
    }
}

If you now run the application, you could receive a HTTP 500 response

As we develop a Web application, which certainly hope to see all of the stack error occurred

可用向 Startup 类的 Configure 方法中加入一行调用 UseDeveloperExceptionPage 的代码,实现这一需求

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;

namespace StatlerWaldorfCorp.WebApp
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        public IConfiguration Configuration { get; set; }

        public void ConfigureServices(IServiceCollection services) {            
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {     
           loggerFactory.AddConsole();
           loggerFactory.AddDebug();       
           
           app.UseDeveloperExceptionPage();
           app.UseMvc(routes =>
           {
               routes.MapRoute("default",
                   template: "{controller=Home}/{action=Index}/{id?}");
           });
           app.UseStaticFiles();
        }
    }
}

有了新的 Startup 类,我们应该能够通过 dotnet restore 以及 dotnet run 启动应用

从 JavaScript 中调用 REST API

首先,我们通过添加新的控制器来创建 API 端点

using Microsoft.AspNetCore.Mvc;
using StatlerWaldorfCorp.WebApp.Models;

namespace StatlerWaldorfCorp.WebApp.Controllers
{
    [Route("api/test")]
    public class ApiController : Controller
    {
        [HttpGet]
        public IActionResult GetTest()
        {
            return this.Ok(new StockQuote { Symbol = "API", Price = 9999 });
        }
    }
}

如果现在再运行应用,可用打开浏览器并访问 http://localhost:5000/api/test,应该能看到一个 JSON 响应

{
    "symbol" : "API",
    "price" : 9999
}

有了可供消费的 API 后,现在来修改我们唯一的视图,让它调用 JavaScript 来消费这个 API

<html>
<head>
    <title>Hello world</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="/Scripts/hello.js"></script>
</head>
<body>
    <h1>Hello World</h1>
    <div>
        <h2>Stock Quote</h2>
        <div>
            Symbol: @Model.Symbol<br/>
            Price: [email protected]<br/>
        </div>
    </div>
    <br/>
    <div>
        <p class="quote-symbol">The Symbol is </p>
        <p class="quote-price">The price is $</p>
    </div>
</body>
</html>

注意,这里决定引入一个 jQuery,以及一个新脚本 hello.js

我们按照约定,把它添加到名为 wwwroot 的新目录 wwwroot/Scripts/hello.js

$(document).ready(function () {
    $.ajax({
        url: "/api/test"
    }).then(function (data) {
        $('.quote-symbol').append(data.symbol);
        $('.quote-price').append(data.price);
    });
});

这些 jQuery 代码非常直观,它们向 API 端点发送 Ajax 请求,返回的对象会包含 symbol 和 price 属性,它们将被附加到新添加的段落标签之中

开发云原生 Web 应用

  • (1)API 优先
  • (2)配置
  • (3)日志
  • (4)会话状态
  • (5)数据保护
  • (6)后端服务
  • (7)环境均等
  • (8)端口绑定
  • (9)遥测
  • (10)身份验证和授权
会话状态

云原生 Web 应用基本上不可能再使用基于内存的会话状态了,而必须使用进程外的提供程序

数据保户

如果涉及数据保护,”进程外存储“的思路同样适用于密钥存储

我们要使用一种现成的密钥保管库,可以是基于云的密钥保管库,也可以是基于 Redis 或其他数据库制作的定制解决方案

端口绑定

不管是使用 docker compose,部署到 Kubernetes,还是使用 AWS、Azure 或者 GCP,应用要想在云环境中运行良好,就要能接受为它预设的任何端口号

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 ([email protected]) 。

Guess you like

Origin www.cnblogs.com/MingsonZheng/p/12275280.html