十年河東,十年河西,莫欺少年窮
學無止境,精益求精
上一節中,學習了NetCore 的web應用程序,因為Cshtml頁面自帶.Cs文件,所以類似於微軟早期的webForm應用。
本節一起學習NetCore 的MVC模式,如下,新建一個項目:
首先在Home控制器中添加如下控制器:

public string Welcome(string name, int ID = 1) { return HtmlEncoder.Default.Encode($"Hello {name}, ID: {ID}"); }
運行項目,如下:
返回一串字符串,注意這里的 HtmlEncoder.Default.Encode() 方法,用於字符串編碼,能防止JavaScript攻擊,即防止XSS攻擊,如果在Url中存在漢字,將會被編碼。
首先准備數據庫數據,如下:
1、新建一個數據庫,命名為:MovieDB
2、創建一張表,命名為:Movie
腳本如下:

create table Movie ( ID int identity(1,1) primary key, Title nvarchar(200), ReleaseDate datetime, Genre varchar(200), Price decimal(18,2) )
數據庫創建完畢,我們插入一條數據:

insert into [MovieDB].[dbo].[Movie] values('戰狼2',getdate(),'影視媒體',18)
數據庫准備完畢,
...
現在准備C#的Model 、數據庫訪問上下文 、及數據庫鏈接字符串
1、在項目 Models 文件夾中添加Movie類:

public class Movie { public int Id { get; set; } public string Title { get; set; } [DataType(DataType.Date)] public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } }
2、添加數據訪問上下文類:

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; namespace MvcMovie.Data { public class MvcMovieContext : DbContext { public MvcMovieContext(DbContextOptions<MvcMovieContext> options) : base(options) { } public DbSet<MvcMovie.Models.Movie> Movie { get; set; } } }
3、在 appsettings.json 中添加鏈接字符串,如下:

{ "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "MvcMovieContext": "Data Source=DESKTOP-VD79APR\\SQLEXPRESS;Initial Catalog=MovieDB;Integrated Security=True" } }
4、在 StartUp類中注冊上下文服務,如下:

public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddDbContext<MvcMovieContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext"))); }
至此:C#配置數據庫部分就搞定了。
但是,可惡的微軟提供的VS2017 采用的NetCore框架的版本是2.1.1,在這個框架下,無法添加控制器和視圖...
所以我的本篇博客似乎只能到此為止了...嗚嗚,查了相關資料,也沒能找到相關的解決方法。
添加控制器時,會報錯,如下:
添加視圖時。也會報錯:
后來,沒有放棄得我,關閉VS后,重新打開,就可以了。ののののののののののののののののののののののののののののののの
奇葩的VS就是這么神奇。
OK,添加控制器和視圖的問題解決了,現在我們就添加相關控制器:MovieController 並 采用模板的形式添加視圖,如下截圖:
右鍵項目,選擇:添加/新搭建基架的項目...如下:
並選擇我們之前創建的上下文類及Model類,如下:
至此,我們項目針對數據表Movie的增刪改查視圖就構造完成了。運行項目如下:
CS 代碼如下:

using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using MvcMovie.Data; using MvcMovie.Models; namespace MvcMovie { public class MoviesController : Controller { private readonly MvcMovieContext _context; public MoviesController(MvcMovieContext context) { _context = context; } // GET: Movies public async Task<IActionResult> Index() { return View(await _context.Movie.ToListAsync()); } // GET: Movies/Details/5 public async Task<IActionResult> Details(int? id) { if (id == null) { return NotFound(); } var movie = await _context.Movie .FirstOrDefaultAsync(m => m.Id == id); if (movie == null) { return NotFound(); } return View(movie); } // GET: Movies/Create public IActionResult Create() { return View(); } // POST: Movies/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price")] Movie movie) { if (ModelState.IsValid) { _context.Add(movie); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } return View(movie); } // GET: Movies/Edit/5 public async Task<IActionResult> Edit(int? id) { if (id == null) { return NotFound(); } var movie = await _context.Movie.FindAsync(id); if (movie == null) { return NotFound(); } return View(movie); } // POST: Movies/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price")] Movie movie) { if (id != movie.Id) { return NotFound(); } if (ModelState.IsValid) { try { _context.Update(movie); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!MovieExists(movie.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(movie); } // GET: Movies/Delete/5 public async Task<IActionResult> Delete(int? id) { if (id == null) { return NotFound(); } var movie = await _context.Movie .FirstOrDefaultAsync(m => m.Id == id); if (movie == null) { return NotFound(); } return View(movie); } // POST: Movies/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(int id) { var movie = await _context.Movie.FindAsync(id); _context.Movie.Remove(movie); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } private bool MovieExists(int id) { return _context.Movie.Any(e => e.Id == id); } } }
具體的代碼及相關知識,會在此系列博客中詳解,今天只是嘗試着搭建一個NETCore MVC 項目。
至此,項目搭建完畢,謝謝。
@天才卧龍的博客