ASP.NET Core Blazor 1:创建准备项目
本章将创建贯穿这一部分的示例项目。
1 创建项目
dotnet new globaljson --sdk-version 3.1.101 --output MyAdvanced dotnet new web --no-https --output MyAdvanced --framework netcoreapp3.1 dotnet new sln -o MyAdvanced dotnet sln MyAdvanced add MyAdvanced
向项目中添加 NuGet 包
dotnet add package Microsoft.EntityFrameworkCore.Design --version 3.1.1 dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 3.1.1
安装全局工具包
dotnet tool uninstall --global dotnet-ef dotnet tool install --global dotnet-ef --version 3.1.1
2 添加数据模型
这个应用程序的数据模型由三个类组成,分别代表人员、工作部门和位置。创建一个 Model 文件夹,并向其中添加一个名为 Person.cs 的类文件。
public class Person { public long PersonId { get; set; } public string Firstname { get; set; } public string Surname { get; set; } public long DepartmentId { get; set; } public long LocationId { get; set; } public Department Department { get; set; } public Location Location { get; set; } }
将一个名为 Department.cs 的类文件添加到 Models 文件夹中。
public class Department { public long Departmentid { get; set; } public string Name { get; set; } public IEnumerable<Person> People { get; set; } }
在 Models 文件夹中添加一个名为 Location.cs 的类文件。
public class Location { public long LocationId { get; set; } public string City { get; set; } public string State { get; set; } public IEnumerable<Person> People { get; set; } }
要创建提供对数据库的访问的 EF Core 的上下文类, Models 文件夹添加 DataContext.cs。
public class DataContext : DbContext { public DataContext(DbContextOptions<DataContext> opts) : base(opts) { } public DbSet<Person> People { get; set; } public DbSet<Department> Departments { get; set; } public DbSet<Location> Locations { get; set; } }
2.1 准备种子数据
将一个名为 SeedData.cs 的类添加到 Models 文件夹中,以定义用于填充数据库的种子数据。
public static class SeedData { public static void SeedDatabase(DataContext context) { context.Database.Migrate(); if (context.People.Count() == 0 && context.Departments.Count() == 0 && context.Locations.Count() == 0) { Department d1 = new Department { Name = "Sales" }; Department d2 = new Department { Name = "Development" }; Department d3 = new Department { Name = "Support" }; Department d4 = new Department { Name = "Facilities" }; context.Departments.AddRange(d1, d2, d3, d4); context.SaveChanges(); Location l1 = new Location { City = "Oakland", State = "CA" }; Location l2 = new Location { City = "San Jose", State = "CA" }; Location l3 = new Location { City = "New York", State = "NY" }; context.Locations.AddRange(l1, l2, l3); context.People.AddRange( new Person { Firstname = "Francesca", Surname = "Jacobs", Department = d2, Location = l1 }, new Person { Firstname = "Charles", Surname = "Fuentes", Department = d2, Location = l3 }, new Person { Firstname = "Bright", Surname = "Becker", Department = d4, Location = l1 }, new Person { Firstname = "Murphy", Surname = "Lara", Department = d1, Location = l3 }, new Person { Firstname = "Beasley", Surname = "Hoffman", Department = d4, Location = l3 }, new Person { Firstname = "Marks", Surname = "Hays", Department = d4, Location = l1 }, new Person { Firstname = "Underwood", Surname = "Trujillo", Department = d2, Location = l1 }, new Person { Firstname = "Randall", Surname = "Lloyd", Department = d3, Location = l2 }, new Person { Firstname = "Guzman", Surname = "Case", Department = d2, Location = l2 }); context.SaveChanges(); } } }
2.2 配置 Entity Framework Core 服务和中间件
对 Startup 类进行更改,它配置 Entity Framewonk Core 并设置 DataContext 服务,将使用该服务访问数据库。
public class Startup { public Startup(IConfiguration config) { Configuration = config; } public IConfiguration Configuration { get; set; } public void ConfigureServices(IServiceCollection services) { services.AddDbContext<DataContext>(opts => { opts.UseSqlServer(Configuration[ "ConnectionStrings:PeopleConnection"]); opts.EnableSensitiveDataLogging(true); }); } public void Configure(IApplicationBuilder app, DataContext context) { app.UseDeveloperExceptionPage(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("controllers", "controllers/{controller=Home}/{action=Index}/{id?}"); endpoints.MapDefaultControllerRoute(); endpoints.MapRazorPages(); }); SeedData.SeedDatabase(context); } }
要定义用于应用程序数据的连接字符串,在 appsetingsjson 文件中添加配置。
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information", "Microsoft.EntityFrameworkCore": "Information" } }, "AllowedHosts": "*", "ConnectionStrings": { "ProductConnection": "Server=.;Database=People;MultipleActiveResultSets=true;User ID=sa;Pwd=Admin123;" } }
2.3 创建和应用迁移
创建 Entity Framework Core 迁移
dotnet ef migrations add Initial
创建迁移后,将其应用到数据库。
dotnet ef database update
3 添加引导 CSS 框架
用引导 CSS 框架为示例应用程序生成的 HTML 元素设置样式要安装引导包。
libman init -p cdnjs libman install twitter-bootstrap@4.3.1 -d wwwroot/lib/twitter-bootstrap
如果使用的是 Visual Studio,可以通过单击项目并从弹出菜单中选择客户端库来安装客户端包。
4 配置服务和中间件
在这个项目中启用运行时 Razor 视图编译,安装提供运行时编译服务的包。
dotnet add package Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation --version 3.1.1
同时会使用 MVC 控制器和 Razor Pages 响应请求。Startup 类中配置应用程序使用的服务和中间件。
services.AddControllersWithViews().AddRazorRuntimeCompilation(); services.AddRazorPages().AddRazorRuntimeCompilation();
public void Configure(IApplicationBuilder app, DataContext context) { app.UseDeveloperExceptionPage(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("controllers", "controllers/{controller=Home}/{action=Index}/{id?}"); endpoints.MapDefaultControllerRoute(); endpoints.MapRazorPages(); }); SeedData.SeedDatabase(context); }
除了默认的控制器路由之外,还添加了一个匹配以控制器开始的 URL 路径的路由,这将使后续章节中的示例在控制器和 Razor Pages 之间切换时更容易理解。这与在前几章中采用的约定相同,把以 /pages 开头的 URL 路径路由到 Razor 页面。
5 创建控制器和视图
添加 Controllers 文件夹,并添加 HomeController.cs。
public class HomeController : Controller { private DataContext context; public HomeController(DataContext dbContext) { context = dbContext; } public IActionResult Index([FromQuery] string selectedCity) { return View(new PeopleListViewModel { People = context.People .Include(p => p.Department).Include(p => p.Location), Cities = context.Locations.Select(l => l.City).Distinct(), SelectedCity = selectedCity }); } } public class PeopleListViewModel { public IEnumerable<Person> People { get; set; } public IEnumerable<string> Cities { get; set; } public string SelectedCity { get; set; } public string GetClass(string city) => SelectedCity == city ? "bg-info text-white" : ""; }
为给控制器提供视图,创建 Views/Home 文件夹,并添加一个名为Index.cshtml 的 Razor 视图。
@model PeopleListViewModel <h4 class="bg-primary text-white text-center p-2">People</h4> <table class="table table-sm table-bordered table-striped"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Dept</th> <th>Location</th> </tr> </thead> <tbody> @foreach (Person p in Model.People) { <tr class="@Model.GetClass(p.Location.City)"> <td>@p.PersonId</td> <td>@p.Surname, @p.Firstname</td> <td>@p.Department.Name</td> <td>@p.Location.City, @p.Location.State</td> </tr> } </tbody> </table> <form asp-action="Index" method="get"> <div class="form-group"> <label for="selectedCity">City</label> <select name="selectedCity" class="form-control"> <option disabled selected>Select City</option> @foreach (string city in Model.Cities) { <option selected="@(city == Model.SelectedCity)"> @city </option> } </select> </div> <button class="btn btn-primary" type="submit">Select</button> </form>
要启用标签助手并添加视图中默认可用的名称空间,请给 Views 文件夹添加一个名为 _ViewImports.cshtml 的 Razor 视图导入文件。
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @using MyAdvanced.Models @using MyAdvanced.Controllers
Views 文件夹添加 _ViewStart.cshtml。
@{ Layout = "_Layout"; }
要创建布局,请创建 Views/Shared 文件夹,并向其中添加一个名为 _Layout.cshtml。
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" /> </head> <body> <div class="m-2"> @RenderBody() </div> </body> </html>
6 创建 Razor Pages
创建 Pages 文件夹,Index.cshtml 的 Razor Pages。
@page "/pages" @model IndexModel <h4 class="bg-primary text-white text-center p-2">People</h4> <table class="table table-sm table-bordered table-striped"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Dept</th> <th>Location</th> </tr> </thead> <tbody> @foreach (Person p in Model.People) { <tr class="@Model.GetClass(p.Location.City)"> <td>@p.PersonId</td> <td>@p.Surname, @p.Firstname</td> <td>@p.Department.Name</td> <td>@p.Location.City, @p.Location.State</td> </tr> } </tbody> </table> <form asp-page="Index" method="get"> <div class="form-group"> <label for="selectedCity">City</label> <select name="selectedCity" class="form-control"> <option disabled selected>Select City</option> @foreach (string city in Model.Cities) { <option selected="@(city == Model.SelectedCity)"> @city </option> } </select> </div> <button class="btn btn-primary" type="submit">Select</button> </form> @functions { public class IndexModel : PageModel { private DataContext context; public IndexModel(DataContext dbContext) { context = dbContext; } public IEnumerable<Person> People { get; set; } public IEnumerable<string> Cities { get; set; } [FromQuery] public string SelectedCity { get; set; } public void OnGet() { People = context.People.Include(p => p.Department) .Include(p => p.Location); Cities = context.Locations.Select(l => l.City).Distinct(); } public string GetClass(string city) => SelectedCity == city ? "bg-info text-white" : ""; } }
要启用标签助手并在 Razor Pages 的 View 部分添加默认可用的名称空间,给 Pages 文件夹添 _Viewlmports.cshtml。
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @using MyAdvanced.Models @using Microsoft.AspNetCore.Mvc.RazorPages @using Microsoft.EntityFrameworkCore
要指定 Razor Pages 的默认布局,给 Pages 文件夹添加 _ViewStart.cshiml。
@{ Layout = "_Layout"; }
要创建布局,给 Pagcs 文件夹添加 _Layout.cshtml的 Razor 布局。
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" /> </head> <body> <div class="m-2"> <h5 class="bg-secondary text-white text-center p-2">Razor Page</h5> @RenderBody() </div> </body> </html>
7 运行
使用浏览器请求 http:/localhost:5000/controllers
和 http:/localhost:5000/pages
。
本文来自博客园,作者:一纸年华,转载请注明原文链接:https://www.cnblogs.com/nullcodeworld/p/18262561
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!