.Net Core我的筆記

目錄html

前言

學習Net Core的我的筆記,記錄前端

建議看微軟官方文檔,看不懂的查一下 教程:ASP.NET Core 入門web

IOC註冊

Startup類中的ConfigureServices方法是用於服務註冊IOCsql

ConfigureServices這個方法是用於服務註冊的,服務就是IOC裏面的類數據庫

三種生命週期

IOC容器內的服務有三種生命週期json

  1. Transient:每次請求都會建立一個新的實例
  2. Scoped:每次Web請求都會建立一個實例
  3. Singleton:一旦實例被建立,一直使用,直到應用中止

如何註冊一個IOC服務

咱們有一個類和一個接口,接口的實現類,這裏不寫,註冊以下c#

public void ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<IStudentService,StudentService>();
        }

寫了一個單例的服務,已經注入了,調用後續再寫windows

管道和中間件

示意圖

下圖很經典,用戶的請求須要通過管道,管道內部能夠寫中間件,若是你什麼都不寫,那麼請求返回的就是固定的,你加了中間件,就會有變化,好比權限驗證,身份驗證,MVC處理等中間件後端

管道方法

Startup類裏面的Configure方法就是管道的方法,能夠在裏面寫中間件api

中間件

app.Run就是運行的一箇中間件,如今咱們寫一個新的中間件

app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Hello World!");
            });
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("許嵩!");
            });

運行,能夠發現,仍是Hello World,根本沒有許嵩,由於中間件根本沒往下執行,能夠這樣設置

app.Use(async (context,next) =>
            {
                await context.Response.WriteAsync("Hello World!");
                await next();
            });
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("許嵩!");
            });

加了一個next,而後執行await next(); 這樣就會執行按照順序的下一個中間件

加日誌觀看

public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILogger<Startup> logger)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.Use(async (context,next) =>
            {
                logger.LogInformation("管道1開啓");
                await context.Response.WriteAsync("Hello World!");
                await next();
                logger.LogInformation("管道1結束");
            });
            app.Run(async (context) =>
            {
                logger.LogInformation("管道2開啓");
                await context.Response.WriteAsync("許嵩!");
                logger.LogInformation("管道2結束");

            });
        }

加了一個日誌ILogger,這樣再運行,注意此次運行不選擇IIS了,咱們選擇Kestrel服務器,就是你的解決方案同名的那個,運行,能夠查看日誌

使用MVC

MVC服務注入

直接新建一個控制器Controller,你會發現,Controller沒有引入,沒法使用.

.net Core和.net Framework不同,.net MVC寫MVC直接就能夠, .net Core須要註冊一下,恰好使用了上面的IOC服務註冊,仍是在Startup類中的ConfigureServices寫:

services.AddMvc();

MVC管道調用

管道調用的時候能夠加一個路由

app.UseMvc(route =>
{
    route.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});

MVC文件夾以及代碼建立

Controllers,Models,Views三個文件夾的建立

新建HomeController,添加Index視圖

public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
@{
    ViewData["Title"] = "Index";
}

<h1>個人第一個.Net Core Web項目</h1>

結果

三種環境配置

有三種官方給的環境,分別是

Development(開發)、Staging (分階段)和 Production(生產)

更改環境變量,點擊項目,右鍵屬性,選擇調試,更改,如圖

在Properties下的launchSettings.json能夠更改不一樣環境的參數配置

{
  "iisSettings": {
    "windowsAuthentication": false, 
    "anonymousAuthentication": true, 
    "iisExpress": {
      "applicationUrl": "http://localhost:13335",
      "sslPort": 44347
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "StudyNetCore": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

Startup能夠判斷環境

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
if (env.IsProduction())
{
    System.Console.WriteLine("...");
}
if (env.IsStaging())
{
    System.Console.WriteLine("...");
}
if (env.IsEnvironment("自定義環境"))
{
    System.Console.WriteLine("...");
}

使用HTTPS

在Startup類中注入HTTPS服務,並設置管道

在ConfigureServices類中注入

services.AddHttpsRedirection(option=> {
    option.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
    option.HttpsPort = 5001;
});

在Configure方法裏面使用HTTPS管道,注意HTTPS管道必須在MVC管道以前,不然沒意義了就

app.UseHttpsRedirection();

在launchSettings.json裏面設置啓動url

改爲這樣就能夠,加了一個launchUrl,初始值爲http://localhost:5000/Home/Index

這樣

{
  "profiles": {
    "StudyNetCore": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "http://localhost:5000/Home/Index",
      "applicationUrl": "https://localhost:5001;http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

EntityFrameWork Core的入門使用

真是一波三折~我開始就遇到報錯了

Build failed.

這個報錯是看看你的項目能不能編譯成功,若是有報錯請解決報錯

嚴重性代碼說明項目文件行禁止顯示狀態錯誤 MSB3541 Files 的值「<<<<<<< HEAD」無效。路徑中具備非法字符。 StudyNetCore D:\Programs\VisualStudio2019\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets

這個錯誤不知道是啥,可是能夠找出來是MVC項目的錯,因此我把MVC項目的obj文件夾下面的全刪了,而後從新編譯一次就能夠了

Unable to create an object of type 'MyContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

這個報錯的緣由是,須要把默認項目改爲MVC的,才能夠執行 Add-Migration InitialCreate,我也不知道爲啥😠

開始EF Core入門

首先須要新建三個項目,一個是主項目,我建的是MVC

一個是Model類庫,一個是操做EF Core的遷移類庫

如圖,我建了三個,DB是來放EF Core遷移文件的,DomainModels是放領域模型的,下面的MVC是業務

第一步,新建幾個Model

我爲了測試,在DomainModels下新建了一個Blog

using System;
using System.Collections.Generic;

namespace DomainModels
{
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public int Rating { get; set; }
        public List<Post> Posts { get; set; }
    }
}

注意,必定要有主鍵,默認有Id或者XXId的都是主鍵

第二步,新建EF Core遷移

在DB裏面使用NuGet引用EF Core,以下

  1. Microsoft.EntityFrameworkCore
  2. Microsoft.EntityFrameworkCore.Design
  3. Microsoft.EntityFrameworkCore.SqlServer
  4. Microsoft.EntityFrameworkCore.Tools

新建DBContext的繼承類,個人是這樣的

using DomainModels;
using Microsoft.EntityFrameworkCore;
using System;

namespace DB
{
    public class MyContext:DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
 optionsBuilder.UseSqlServer("Server=.;Database=EFCore;Trusted_Connection=True;");
//若是是帶用戶名密碼的這樣寫   optionsBuilder.UseSqlServer("server=192.168.3.8;uid=sa;pwd=123;database=VaeDB;");

        }
        public DbSet<Blog> Blogs { get; set; }
    }
}

開始遷移,在視圖->其餘窗口->包管理控制檯

首先輸入: Add-Migration InitialCreate 後面的是名稱,隨意寫,我寫的InitialCreate

而後執行遷移文件:Update-Database

等待一會,你就會發現本地的數據庫裏面已經有了EFCore數據庫和Blogs數據表了

第三步,簡易的增刪改查

在MVC項目裏面新建了一個Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DB;
using DomainModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace StudyNetCore.Controllers
{
    public class EFCoreController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
        public void Add()
        {
            using (var context = new MyContext())
            {
                var blog = new Blog {
                    Url = "http://sample.com",
                    Rating=98
                };
                context.Blogs.Add(blog);
                context.SaveChanges();
            }
        }
        public void Remove()
        {
            using (var context = new MyContext())
            {
                var blog = context.Blogs.Single(b => b.BlogId == 2);
                context.Blogs.Remove(blog);
                context.SaveChanges();
            }
        }
        public void Update()
        {
            using (var context = new MyContext())
            {
                var blog = context.Blogs.Single(b => b.BlogId == 1);
                blog.Url = "http://www.vae.com";
                context.SaveChanges();
            }
        }
        public void Select()
        {
            using (var context = new MyContext())
            {
                var blogs = context.Blogs.ToList();
                Console.WriteLine(blogs);
            }
        }
    }
}

運行項目,輸入對應的url,成功操做了數據

EF Core的數據庫鏈接字符串寫在配置文件中

上面的數據庫配置文件是寫在MyContext裏面的,這樣不合適,因此我寫在了json文件裏

appsettings.json

找到appsettings.json,在裏面加上

"ConnectionStrings": {
    "DefaultConnection": "Server=.;Database=EFCore;Trusted_Connection=True;"
  }

Statrtup注入

在Startup裏面的ConfigureServices方法裏面寫

public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; set; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<MyContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddSingleton<IStudentService,StudentService>();
            services.AddMvc();

MyContext修改

public class MyContext : DbContext
    {
        public MyContext(DbContextOptions<MyContext> options)
            : base(options)
        {
        }

        public DbSet<Blog> Blogs { get; set; }

    }

使用EFCore

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DB;
using DomainModels;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace StudyNetCore.Controllers
{
    public class EFCoreController : Controller
    {
        private readonly MyContext _myContext;
        public EFCoreController(MyContext myContext)
        {
            _myContext = myContext;
        }

        public IActionResult Index()
        {
            return View();
        }
        public void Add()
        {
            var blog = new Blog
            {
                Url = "http://sample.com",
                Rating = 98
            };
            _myContext.Blogs.Add(blog);
            _myContext.SaveChanges();
        }
        public void Remove()
        {
            var blog = _myContext.Blogs.Single(b => b.BlogId == 2);
            _myContext.Blogs.Remove(blog);
            _myContext.SaveChanges();
        }
        public void Update()
        {
            var blog = _myContext.Blogs.Single(b => b.BlogId == 1);
            blog.Url = "http://www.vae.com";
            _myContext.SaveChanges();
        }
        public IActionResult Select()
        {
            var list = _myContext.Blogs.ToList();
            Console.WriteLine(list);
            return View();
        }
    }
}

EntityModel和ViewModel的轉化使用

和數據庫表字段對應的就是EntityModel,和視圖對應的就是ViewModel

我新建一個EntityModel,以下

public class Student
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDay { get; set; }
}

能夠看到,學生有兩個名字,還有出生年月日,可是我頁面上只想看到一個名字和年齡,這就須要處理一下了,ViewModel以下

public class HomeIndexViewModel
{
    public string Name { get; set; }
    public int Age { get; set; }
}

轉化以下:

private readonly StudentService _studentService=new StudentService();

public IActionResult Index()
{
    List<Student> studentList = _studentService.getStudentList();
    var vms = studentList.Select(x => new HomeIndexViewModel
    {
        Name = x.FirstName + x.LastName,
        Age = DateTime.Now.Subtract(x.BirthDay).Days / 365
    });
    return View(vms);
}

視圖使用以下:

@model IEnumerable<StudyNetCore.ViewModels.HomeIndexViewModel>
@{
    ViewData["Title"] = "Index";
}

<h1>個人第一個.Net Core Web項目</h1>

<h1>Student的ViewModel數據展現</h1>
<ul>
    @foreach (var item in Model)
    {
        <li>@item.Name - @item.Age</li>
    }
</ul>

@model是指令,只是爲了讓@Model有智能提示

結果以下:

輸入Model和防止重複post

前端HTML輸入Model傳給後臺我知道,待補充

待補充

而後頁面重複刷新會形成post的重複提交,解決辦法就是post提交一次以後就當即重定向,以下

return RedirectToAction(nameof(Detail));

Model數據驗證

一個輸入的表單,例如我輸入用戶的姓名,年齡,手機號,郵箱,密碼等等,這個對應的Model須要作數據驗證

可能有人會問,前端我驗證不就得了,前端數據填寫不合法的時候就報錯,後端的Model還驗證什麼呢?我之前也是這麼想的

直到我知道了PostMan.....

有不少方法能夠繞過你的前端驗證的,若是你沒加後端驗證,有人直接傳入非法數據就不安全了

因此,數據驗證.先後端都須要作,雙重保險

相似這樣

public class Student
    {
        [Required]
        public int Id { get; set; }
        [StringLength(20)]
        public string FirstName { get; set; }
        public string LastName { get; set; }
        [DataType(DataType.Date)]
        public DateTime BirthDay { get; set; }
    }

下面列了一些,更多的用到再更新

[Required]//必須數據
[StringLenght(100)]//最大長度100
[Range(0,999)]//取值範圍是0-999
[DateType(DataType.Date)]//要求此數據必爲日期類型
[CreaitCard]//信用卡
[Phone]//電話號碼
[EmailAddress]//郵箱地址
[DataType(DataType.Password)] //密碼
[Url]//必須是url連接
[Compare]//比較數據是否相同

例子

public class Movie
{
    public int ID { get; set; }

    [StringLength(60, MinimumLength = 3)]
    [Required]
    public string Title { get; set; }

    [Display(Name = "Release Date")]
    [DataType(DataType.Date)]
    public DateTime ReleaseDate { get; set; }

    [Range(1, 100)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Price { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$")]
    [Required]
    [StringLength(30)]
    public string Genre { get; set; }

    [RegularExpression(@"^[A-Z]+[a-zA-Z0-9""'\s-]*$")]
    [StringLength(5)]
    [Required]
    public string Rating { get; set; }
}
  • RequiredMinimumLength 特性表示屬性必須有值;但用戶可輸入空格來知足此驗證。
  • RegularExpression 特性用於限制可輸入的字符。 在上述代碼中,即「Genre」(分類):
    • 只能使用字母。
    • 第一個字母必須爲大寫。 不容許使用空格、數字和特殊字符。
  • RegularExpression「Rating」(分級):
    • 要求第一個字符爲大寫字母。
    • 容許在後續空格中使用特殊字符和數字。 「PG-13」對「分級」有效,但對於「分類」無效。
  • Range 特性將值限制在指定範圍內。
  • StringLength 特性使你可以設置字符串屬性的最大長度,以及可選的最小長度。

View

_Layout.cshtml

這個是母版頁,有兩個地方須要說明

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <div>
        @RenderBody()
    </div>
</body>
</html>

第一個@ViewBag.Title 子頁面能夠這樣寫,這樣就標題映射過去了

@{
    ViewBag.Title="Index";
}

下面的@RenderBody()就是你子頁面展示的地方

還能夠寫一個母版頁節點,讓子頁面去加載,例如

@RenderSection("Footer",required:false)

這樣子頁面就可使用

@section Footer{
    <h3>你們好,我是腳</h3>
}

required:false是否是每一個頁面必須的,若是不寫,每一個子頁面都得加載Footer節點

_ViewStart.cshtml

這個是每一個頁面加載以前都必須先加載的頁面,一般直接放在Views的文件夾下面,這樣就能夠對全部的頁面起做用了.若是把_ViewStart.cshtml放在了Home文件夾下面,那麼僅僅對Home文件夾下的頁面起做用

例如,咱們能夠把每一個頁面都有的東西放在_ViewStart.cshtml裏面

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>都得先加載我</h1>

_ViewImports.cshtml

有時候咱們會在視圖裏面用到本身寫的類,這個時候咱們一般是直接寫全引用,或者在頁面上寫@using

可是,每個頁面都寫重複的@using這樣就很差了,能夠統一的在_ViewImports.cshtml裏寫@using

這樣每一個頁面直接寫類的名稱就能夠了,好比

@using StudyNetCore.Models;

一般放在Views文件夾下

_PartialView.chhtml

這個是分部視圖,多個頁面都用到的HTML能夠放到這裏面,一般放在Share文件夾下

@model IEnumerable<HomeIndexViewModel>

<h1>我是分部視圖</h1>

<ul>
    @foreach (var item in Model)
    {
        <li>@item.Name</li>
        <li>@item.Age</li>
    }
</ul>

調用的時候也很簡單,輸入名字傳入Model就能夠了

@Html.Partial("_PartialView",Model)
<partial name="_PartialView" for="HomeIndexViewModel" />

這兩種方式均可以,可是推薦使用TagHelper方式

缺點,分部視圖PartialView的缺點就是,這個Model必須是調用者傳過來的,不能本身去查詢加載數據,下面的ViewComponents就很好的解決了這個問題

ViewConponents

暫時不寫,感受略麻煩,感受可使用ViewBag代替

Identity:身份驗證

兩個主要的類先了解一下

  • UserManager :操做用戶,例如建立用戶,刪除用戶等

  • SignInManager :對用戶進行身份驗證

使用TagHelper

在_ViewImports.cshtml裏面加上

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

而後頁面就能夠直接調用,如

<a asp-controller="Home" asp-action="data">仍是點我,TagHelper類型的</a>

爲何使用TagHelper?由於改變路由以後這些會自動映射

防止js惡意注入

若是返回的是字符類型,那麼可使用 $ 符號進行拼接,仍是不錯的挺好用,

HtmlEncoder.Default.Encode這個東西是防止js注入的,可是我嘗試中文也顯示的被編碼過了,我不知道怎麼不讓中文被編碼

public string Index(string name, int age=17)
{
    return HtmlEncoder.Default.Encode($"Hello {name},you age is {age}");
}

字段重命名DisplayNameFor和Display

Model和數據庫的字段都是一一對應的,可是我有一個這樣的名字,以下

public DateTime ReleaseDate { get; set; }

ReleaseDate這個名字顯然不合適,加一個空格就好多了,能夠這樣寫

[Display(Name = "Release Date")]
public DateTime ReleaseDate { get; set; }

前端顯示就使用@Html.DisplayNameFor,以下

<th>
    @Html.DisplayNameFor(model => model.ReleaseDate)
</th>

這樣一來顯示的就是有空格的名字了

這樣講一下@Html.DisplayNameFor就是現實名字,@Html.DisplayFor就是顯示數據

我後臺傳入的是一個List,以下

public IActionResult Test()
{
    return View(_context.Movie.ToList());
}

前端接受使用model,而後處理的時候可使用以下

@model IEnumerable<DomainModels.Movie>
@{
    ViewData["Title"] = "Test";
}

<h1>我就是Movie下面的一個Test頁面</h1>

<div>
    <ul>
        @foreach (var item in Model)
        {
        <li>
            名字是: @Html.DisplayNameFor(model => model.Title)  |  內容是: @Html.DisplayFor(modelItem => item.Title)
            類別是: @Html.DisplayNameFor(model => model.Genre)  |  內容是: @Html.DisplayFor(modelItem => item.Genre)
            價格是: @Html.DisplayNameFor(model => model.Price)  |  內容是: @Html.DisplayFor(modelItem => item.Price)
        </li>
        }
    </ul>
</div>

講一下標題可使用model => model.Title

內容的話必須使用modelItem => item.Title,其中前面的modelItem 隨意寫,後面的 item.Title是必須使用的

WebAPI

這個WebAPI和MVC有什麼區別呢?其實他倆乍一看很像,都是控制器加Action的模式

可是我以爲最大的區別就在於,MVC是有視圖的,這個框架包含了不少東西

WebAPI呢根本就沒有視圖這個東西,因此內容比較純淨,就是單純的操做數據

很明顯的區別就是一個繼承的是Controller,一個繼承的是ApiController

新建WebAPI

這個實在沒什麼講的,直接新建便可,使用EF Core來操做數據庫,貼幾個代碼看看

using System.Collections.Generic;
using System.Linq;
using DB;
using DomainModels;
using Microsoft.AspNetCore.Mvc;

namespace WebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TodoItemController : ControllerBase
    {
        private readonly MyContext _context;
        public TodoItemController(MyContext context)
        {
            _context = context;
        }

        // GET: api/TodoItem
        [HttpGet]
        public IEnumerable<TodoItem> Get()
        {
            return _context.TodoItem.ToList();
        }

        // GET: api/TodoItem/5
        [HttpGet("{id}", Name = "Get")]
        public TodoItem Get(int id)
        {
            return _context.TodoItem.FirstOrDefault(m => m.Id == id);
        }

        // POST: api/TodoItem
        [HttpPost]
        public void Post(TodoItem todoItem)
        {
            _context.TodoItem.Add(todoItem);
            _context.SaveChanges();
        }

        [HttpPut("{id}")]
        public IActionResult Put(int id, TodoItem todoItem)
        {
            if (id != todoItem.Id)
            {
                return BadRequest();
            }
            _context.TodoItem.Update(todoItem);
            _context.SaveChanges();
            return Ok("ok");
        }

        // DELETE: api/ApiWithActions/5
        [HttpDelete("{id}")]
        public IActionResult Delete(int id)
        {
            TodoItem todoItem = _context.TodoItem.Find(id);
            if (todoItem == null)
            {
                return NotFound();
            }
            _context.TodoItem.Remove(todoItem);
            _context.SaveChanges();
            return Ok("ok");
        }
    }
}

使用PostMan測試API接口

MVC能夠直接輸入控制器測試,反正有視圖能夠看,可是WebAPI這樣的須要使用PostMan進行測試

我暫時是直接運行着項目測試的,稍後再講部署的問題

Get

Post

這個稍微講一下,參數是json格式的,因此必須選擇json,默認是Text格式的,不改爲json就會失敗

還有一個地方就是禁止Postman的SSL證書,不然也會失敗

禁用SSL證書以下

Put

Delete

EF Core根據數據庫表生成Model

這個真的是太好用了,把你的項目設置爲啓動項目,而後 工具>NuGet包管理器>程序包管理器控制檯

在程序包管理器控制檯輸入如下

Scaffold-DbContext "Server=192.168.111.111;Database=VaeDB;uid=sa;pwd=123456789;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

這個很簡單能夠理解,你的數據庫鏈接字符串,最後是導出的位置是Models,也就是你這個啓動項目的Models文件夾下

運行一下,Models就直接生成了

安全

防止CSRF攻擊

//防止CSRF攻擊
services.AddAntiforgery(options =>
{
    //使用cookiebuilder屬性設置cookie屬性。
    options.FormFieldName = "AntiforgeryKey_Censtry";
    options.HeaderName = "X-CSRF-TOKEN-CENSTRY";
    options.SuppressXFrameOptionsHeader = false;
});
headers: {
    "X-CSRF-TOKEN-yilezhu": $("input[name='AntiforgeryKey_yilezhu']").val()
}

發佈

Windows

控制檯直接運行

點擊你的項目發佈,而後你在發佈的文件夾內能夠看到一個項目名.dll,直接右鍵打開控制檯輸入

dotnet Web.dll --urls=http://localhost:8099

固然也能夠不指定訪問端口號,不寫 --urls後面的便可

IIS部署

Swagger的使用

首先要知道Swagger是什麼,學了有什麼用

Swagger是什麼?

就是一個自動生成API文檔的框架

Swagger學了能幹嗎?

你編寫了一個API的後端程序,須要給其餘人調用,總得寫個文檔吧,否則別人怎麼知道有哪些API接口,分別是幹嗎的

你固然能夠選擇本身一個一個的寫,也能夠選擇使用Swagger自動生成而後喝杯茶

如何使用Swagger

引入Nuget包

使用Nuget引入Swagger的包,就是這個:Swashbuckle.AspNetCore

在Startup類裏配置

Startup裏面有兩個地方須要配置,首先是須要注入一下服務,而後在中間件那裏啓用一下

首先,服務注入,在ConfigureServices方法添加Swagger

//Swagger
services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { 
        //只列舉了幾個,還有不少沒寫,詳細可查官方文檔
        Title = "My API",
        Version = "v1", 
        Description="個人API的說明文檔"
    });
});

而後在中間件的方法Configure中,啓用Swagger

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});

查看Swagger效果

運行你的Web API項目,而後路由輸入swagger,便可

以上簡簡單單的導入包,注入服務,啓用中間件就能夠看到簡單的文檔了,如圖

一目瞭然,接口,還能夠測試接口,像postman同樣

Swagger進階

上面簡單的實現了Swagger,如今來進階一下,增長几個功能

  1. 運行API項目後首頁直接就是Swagger頁面
  2. 加一個接口的描述
  3. 加一個接口的權限驗證

首頁便是Swagger

先解決第一個問題,運行項目以後首頁直接就是Swagger,這個要在launchSettings.json裏面設定,在Properties下找到launchSettings.json,修改launchUrl

有兩個地方,一個是profiles下的launchUrl,還有一個是項目下的launchUrl

"launchUrl": "swagger",

接口描述

第二個問題,就是API註釋,找到你的項目,右鍵屬性,來到生成這裏,勾選下面的輸出XML文檔文件,我這裏是項目的根目錄,位置本身隨便選,而後選定以後從新編譯一下項目便可生成xml文件,此時,你會發現出現了很是多的警告,能夠在上面的錯誤和警告那裏加一個 ;1591 這樣就不會有那麼多警告了

在你的API接口上加上註釋,如

/// <summary>
/// TodoItem根據Id獲取
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public TodoItem Get(int id)
{
    return _context.TodoItem.FirstOrDefault(m => m.Id == id);
}

這樣運行項目就能夠有註釋了,如圖

雖然新建了一個xml,可是裏面什麼咱們都沒加,你如今能夠點進去看看,發現xml裏面多了好多內容,就是咱們剛纔寫的接口的註釋

若是某些接口不但願別人看到的話,能夠這樣寫

/// <summary>
/// TodoItem獲取全部
/// </summary>
/// <returns></returns>
[HttpGet]
[ApiExplorerSettings(IgnoreApi = true)]
public IEnumerable<TodoItem> Get()
{
    return _context.TodoItem.ToList();
}

加一個[ApiExplorerSettings(IgnoreApi = true)]就能夠了

接口權限

第三個問題權限

相關文章
相關標籤/搜索