关于 Blazor 应用以及如何使用 VS 2019、.NET Core 3、Web API 创建 ASP.NET Core Blazor CRUD 应用的必知信息






4.64/5 (27投票s)
如何使用 Visual Studio 2019、.NET Core 3、Entity Framework 和 Web API 为 ASP.NET Core Blazor 创建一个简单的 CRUD 应用程序
引言
在本文中,我们将看到如何使用 Visual Studio 2019、.NET Core 3、Entity Framework 和 Web API 为 ASP.NET Core Blazor 创建一个简单的 CRUD 应用程序。Blazor 是 Microsoft 推出的一个新框架。
Blazor
Blazor 有两种应用程序开发方式,一种是 Blazor 客户端应用(目前处于预览阶段),另一种是 Blazor 服务器应用。Blazor 客户端应用运行在 WebAssembly 中,Blazor 服务器应用通过 SignalR 运行。Blazor 应用可以使用 C#、Razor 和 HTML 创建,而不是 JavaScript。Blazor WebAssembly 适用于所有现代 Web 浏览器,包括移动浏览器。Blazor 的主要优势在于 C# 代码文件和 Razor 文件被编译成 .NET 程序集。Blazor 具有可重用的组件,Blazor 组件可以是页面、对话框或输入表单,Blazor 也用于创建单页应用程序。Blazor 用于创建两种应用程序,一种是 Blazor 客户端应用,另一种是 Blazor 服务器端应用。在这里,我们将看到更多关于
Blazor 客户端应用
- Blazor 客户端仍处于预览阶段。
- Blazor 客户端使用 Web Assembly。
- 在 Blazor 客户端中,所有 .NET DLL 都将下载到浏览器。下载大小可能更大,并且由于所有下载都发生在客户端浏览器中,加载可能会有一些时间延迟。
- Blazor 客户端应用程序不需要服务器端依赖。
- 所有类似的 JavaScript 编码都可以在 Blazor 客户端应用中完成,并且实际上不需要使用 JavaScript Interop。
- 它可以部署为静态站点,这意味着它也支持离线。
- 调试比 Blazor 服务器端更复杂。
- 在客户端,数据库连接泄露以及所有应用程序代码都将在客户端,并且安全级别不是很好。
Blazor 服务器应用
- 所有组件处理都将在服务器中进行。
- Blazor 服务器使用 SignalR 连接从 Web 服务器连接到浏览器。
- 在客户端,不会发生数据库连接泄露,因为所有操作都将在服务器中进行。
- 所有表单连接都将在服务器端进行,并且不会下载任何 DLL 到客户端,因为所有 DLL 都将在 Web 服务器中。
- 下载大小小,加载时间比 Blazor 客户端应用更快。
- 我们可以在 Blazor 服务器端使用 .NET Core。
- Blazor 服务器端调试非常棒。
- 在任何 Web 浏览器中运行,因为不需要 WebAssemble。
- 每个浏览器会话都通过 SignalR 连接打开。
背景
必备组件
Using the Code
步骤 1 - 创建数据库和表
我们将使用 SQL Server 数据库来支持我们的 WEB API 和 EF。首先,我们创建一个名为 CustDB
的数据库和一个名为 CustDB
的表。这是用于创建数据库表和在我们表中插入示例记录的 SQL 脚本。在您的本地 SQL Server 中运行以下查询,以创建将在我们的项目中使用的数据库和表。
USE MASTER
GO
-- 1) Check for the Database Exists .If the database is exist then drop and create new DB
IF EXISTS (SELECT [name] FROM sys.databases WHERE [name] = 'CustDB' )
DROP DATABASE CustDB
GO
CREATE DATABASE CustDB
GO
USE CustDB
GO
-- 1) //////////// Customer Masters
IF EXISTS ( SELECT [name] FROM sys.tables WHERE [name] = 'CustomerMaster' )
DROP TABLE CustomerMaster
GO
CREATE TABLE [dbo].[CustomerMaster](
[CustCd] [varchar](20) NOT NULL ,
[CustName] [varchar](100) NOT NULL,
[Email] [nvarchar](100) NOT NULL,
[PhoneNo] [varchar](100) NOT NULL,
[InsertBy] [varchar](100) NOT NULL,
PRIMARY KEY (CustCd)
)
-- insert sample data to Student Master table
INSERT INTO [CustomerMaster] (CustCd,CustName,Email,PhoneNo,InsertBy)
VALUES ('C001','ACompany','acompany@gmail.com','01000007860','Shanun')
INSERT INTO [CustomerMaster] (CustCd,CustName,Email,PhoneNo,InsertBy)
VALUES ('C002','BCompany','bcompany@gmail.com','0100000001','Afraz')
INSERT INTO [CustomerMaster] (CustCd,CustName,Email,PhoneNo,InsertBy)
VALUES ('C003','CCompany','ccompany@gmail.com','01000000002','Afreen')
INSERT INTO [CustomerMaster] (CustCd,CustName,Email,PhoneNo,InsertBy)
VALUES ('C004','DCompany','dcompany@gmail.com','01000001004','Asha')
select * from CustomerMaster
步骤 2 - 创建 ASP.NET Core Blazor 服务器应用程序
安装完上面列出的所有先决条件后,点击桌面上的 开始 >> 程序 >> Visual Studio 2019 >> Visual Studio 2019。点击 新建 >> 项目。
选择 Blazor 应用 并点击 下一步 按钮。
选择您的项目文件夹并输入您的项目名称,然后点击 创建 按钮。
选择 Blazor 服务器应用。
创建 ASP.NET Core Blazor 服务器应用程序后,等待几秒钟。您将在解决方案资源管理器中看到以下结构
在 Data 文件夹中,我们可以添加所有的模型、DBContext 类、服务和控制器,我们将在本文中看到。
在 Pages 文件夹中,我们可以添加所有组件文件。所有组件文件都应该以 .razor 扩展名作为文件名。
在 Shared 文件夹中,我们可以添加所有左侧菜单的 NavMenu.razor 文件,并从 MainLayout.razor 文件更改主要内容。
在 _Imports.razor 文件中,我们可以看到所有导入集都已添加,以便在所有组件页面中使用。
在 App.razor 文件中,我们将添加在浏览器中运行应用程序时默认显示的主组件。Appsertings.json 可用于添加连接字符串。
Startup.cs 文件是一个重要的文件,我们在这里添加所有端点示例,例如控制器端点、HTTP 客户端、添加服务和 dbcontext,以便在启动 Configuration
方法中使用。
运行以测试应用程序
当我们运行应用程序时,我们可以看到左侧有导航,右侧包含数据。我们可以看到默认的示例页面和菜单将显示在我们的 Blazor 网站中。我们可以使用这些页面,也可以删除它们并开始创建我们自己的页面。
在组件中调试
Blazor 的巨大优势在于我们可以在 Razor 中使用 C# 代码,并在代码部分设置断点,在浏览器中,我们可以调试并检查我们的所有业务逻辑是否正常工作,并使用断点轻松追踪任何类型的错误。
为此,我们使用现有的 Counter 组件页面。
这是我们 Counter 页面的实际代码,在 Counter 中我们可以看到有一个按钮,点击按钮会调用方法来执行增量操作。
我们再添加一个按钮,并在按钮点击事件中调用该方法并将名称绑定到我们的组件页面中。
在 HTML 设计部分,我们添加以下代码
<h1>My Blozor Code part</h1>
My Name is : @myName <br />
<button @onclick="ClickMe">Click Me</button>
注意:所有 C# 代码部分和函数都可以写在 @code {}
部分下。
我们添加方法 ClickMe
并声明属性以将名称绑定到 @Code
部分中。
[Parameter]
public string myName { get; set; }
private void ClickMe()
{
myName="Shanu";
}
完整的 Counter 组件页面代码将如下所示
现在让我们在 ClickMe
方法中添加断点
运行程序并打开计数器页面。
我们可以看到,当我们点击 Click Me 按钮时,我们可以调试并检查我们放置的断点中的值。
现在让我们看看如何使用 EF 和 Web API 在 Blazor 中执行 CRUD 操作。
步骤 3 - 使用 Entity Framework
要在我们的 Blazor 应用程序中使用 Entity Framework,我们需要安装以下包
安装包
Microsoft.EntityFrameworkCore.SqlServer
- 用于使用 EF 和 SQL ServerMicrosoft.EntityFrameworkCore.Tools
- 用于使用 EF 和 SQL ServerMicrosoft.AspNetCore.Blazor.HTTTPClient
- 用于从我们的 Blazor 组件与 WEB API 进行通信
首先,我们将添加 Microsoft.EntityFrameworkCore.SqlServer
。为此,右键单击项目并单击 管理 NuGet 包。
搜索所有三个包并安装所有需要的包,如下图所示。
添加数据库连接字符串
打开 appsetting 文件并添加连接字符串,如下图所示
"ConnectionStrings": {
"DefaultConnection": "Server= DBServerName;Database=CustDB;
user id= SQLID;-password=SQLPWD;Trusted_Connection=True;MultipleActiveResultSets=true"
},
创建模型类
接下来,我们需要创建 Model
类,该类与我们的 SQL 表同名,并且还定义与我们的 SQL 字段名相似的属性字段,如下所示。
右键单击 Data 文件夹并创建一个名为 “CustomerMaster.cs” 的新类文件
在该类中,我们添加了与我们的表列同名的属性字段,如下面的代码所示
[Key]
public string CustCd { get; set; }
public string CustName { get; set; }
public string Email { get; set; }
public string PhoneNo { get; set; }
public string InsertBy { get; set; }
创建 dbContext 类
接下来,我们需要创建 dbContext
类。右键单击 Data 文件夹并创建一个名为 “SqlDbContext.cs” 的新类文件
我们将以下代码添加到 DbContext
类中,以便添加 SQLContext
并为我们的 CustomerMaster
模型添加 DBset
。
public class SqlDbContext:DbContext
{
public SqlDbContext(DbContextOptions<SqlDbContext> options)
: base(options)
{
}
public DbSet<BlazorCrudA1.Data.CustomerMaster> CustomerMaster { get; set; }
}
在启动时添加 DbContext
将 DbContext
添加到 Startup.cs 文件中的 ConfigureServices
方法中,如下面的代码所示,我们还提供了用于连接 SQLServer 和 DB 的连接字符串。
services.AddDbContext<SqlDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
请注意,在 ConfigureServices
方法中,我们还可以看到已添加了 weatherforecast
服务。如果创建新服务,则需要将服务添加为 ConfigureServices
方法中的以下代码。
services.AddSingleton<WeatherForecastService>();
为 CRUD 操作创建 Web API
要创建我们的 WEB API 控制器,右键单击 Controllers 文件夹。点击 添加新控制器。
在这里,我们将使用 Scaffold
方法来创建我们的 WEB API。我们选择带有操作的 API 控制器,使用 Entity Framework,然后点击 添加 按钮。
选择我们的 模型类 和 DBContext 类,然后点击 添加 按钮。
我们的 WEB API,包含用于执行 CRUD 操作的 Get
/Post
/Put
和 Delete
方法将自动创建,由于我们已对所有操作和方法使用了 Scaffold
方法并添加了代码,因此现在无需在 Web API 中编写任何代码。
为了测试 Get
方法,我们可以运行我们的项目并复制 GET
方法的 API 路径。在这里,我们可以看到获取 /api/CustomerMasters/
的 API 路径。
运行程序并粘贴 API 路径以测试我们的输出。
如果您看到此错误,这意味着我们需要在 Startup.cs 文件的 Configure
方法中添加控制器的端点。
在 Startup.cs 文件的 Configure
方法中添加以下代码。
endpoints.MapControllers();
我们在 Configure
方法中将以下代码添加到 UseEndpoints
内部。
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
现在再次运行并检查 /api/CustomerMasters/ 以查看数据库中的 Json 数据。
现在我们将把所有这些 WEB API Json 结果绑定到组件中。
处理客户端项目
首先,我们需要添加 Razor 组件页面。
添加 Razor 组件
要添加 Razor 组件页面,右键单击客户端项目中的 Pages 文件夹。点击 添加 >> 新项 >> 选择 Razor 组件 >> 输入您的组件名称。这里,我们将其命名为 Customerentry.razor。
请注意,所有组件文件都需要具有 .razor 扩展名。
在 Razor 组件页面中,我们有三个代码部分:第一部分是导入部分,我们导入所有引用和模型以在组件中使用;HTML 设计和数据绑定部分;最后,我们有函数部分,用于调用所有 Web API 以绑定到我们的 HTML 页面,并执行客户端业务逻辑以显示在组件页面中。
导入部分
首先,我们在 Razor 视图页面中导入所有需要的支持文件和引用。在这里,我们首先导入了要在视图中使用的 Model
类,还导入了 HTTPClient
以调用 Web API 来执行 CRUD 操作。
@page "/customerentry"
@using BlazorCrudA1.Data
@using System.Net.Http
@inject HttpClient Http
@using Microsoft.Extensions.Logging
为服务器端 Blazor 注册 HTTPClient
为了在 Blazor 服务器端使用 HTTPClient
,我们需要在 Startup.cs 的 ConfigureServices
方法中添加以下代码。
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
// Server Side Blazor doesn't register HttpClient by default
if (!services.Any(x => x.ServiceType == typeof(HttpClient)))
{
// Setup HttpClient for server side in a client side compatible fashion
services.AddScoped<HttpClient>(s =>
{
// Creating the URI helper needs to wait until the
// JS Runtime is initialized, so defer it.
var uriHelper = s.GetRequiredService<NavigationManager>();
return new HttpClient
{
BaseAddress = new Uri(uriHelper.BaseUri)
};
});
}
HTML 设计和数据绑定部分
接下来,我们设计我们的 Customer Master details
页面,以显示数据库中的 Customer
详细信息,并创建了一个表单来插入和更新 Customer details
。我们还有 Delete 按钮,用于从数据库中删除 Customer
记录。
在 Blazor 中进行绑定时,我们使用 @bind="@custObj.CustCd"
,并通过 @onclick="@AddNewCustomer"
调用方法。
<h1> ASP.NET Core BLAZOR CRUD demo for Customers</h1>
<hr />
<table width="100%" style="background:#05163D;color:honeydew">
<tr>
<td width="20"> </td>
<td>
<h2> Add New Customer Details</h2>
</td>
<td> </td>
<td align="right">
<button class="btn btn-info" @onclick="@AddNewCustomer">Add New Customer</button>
</td>
<td width="10"> </td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
<hr />
@if (showAddrow == true)
{
<form>
<table class="form-group">
<tr>
<td>
<label for="Name"
class="control-label">Customer Code</label>
</td>
<td>
<input type="text"
class="form-control" @bind="@custObj.CustCd" />
</td>
<td width="20"> </td>
<td>
<label for="Name"
class="control-label">Customer Name</label>
</td>
<td>
<input type="text"
class="form-control" @bind="@custObj.CustName" />
</td>
</tr>
<tr>
<td>
<label for="Email" class="control-label">Email</label>
</td>
<td>
<input type="text"
class="form-control" @bind="@custObj.Email" />
</td>
<td width="20"> </td>
<td>
<label for="Name"
class="control-label">Phone</label>
</td>
<td>
<input type="text"
class="form-control" @bind="@custObj.PhoneNo" />
</td>
</tr>
<tr>
<td>
<label for="Name"
class="control-label">Insert By</label>
</td>
<td>
<input type="text"
class="form-control" @bind="@custObj.InsertBy" />
</td>
<td width="20"> </td>
<td>
</td>
<td>
<button type="submit"
class="btn btn-success"
@onclick="@AddCustomer"
style="width:220px;">Save</button>
</td>
</tr>
</table>
</form>
}
<table width="100%" style="background:#0A2464;color:honeydew">
<tr>
<td width="20"> </td>
<td>
<h2>Customer List</h2>
</td>
</tr>
<tr>
<td colspan="2"></td>
</tr>
</table>
@if (custs == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Customer Code</th>
<th>Customerr Name</th>
<th>Email</th>
<th>Phone</th>
<th>Inserted By</th>
</tr>
</thead>
<tbody>
@foreach (var cust in custs)
{
<tr>
<td>@cust.CustCd</td>
<td>@cust.CustName</td>
<td>@cust.Email</td>
<td>@cust.PhoneNo</td>
<td>@cust.InsertBy</td>
<td><button class="btn btn-primary"
@onclick="@(async () =>
await EditCustomer(cust.CustCd))"
style="width:110px;">Edit</button></td>
<td><button class="btn btn-danger"
@onclick="@(async () =>
await DeleteCustomer(cust.CustCd))">
Delete</button></td>
</tr>
}
</tbody>
</table>
}
函数部分
函数部分用于调用所有 Web API 以绑定到我们的 HTML 页面,并执行客户端业务逻辑以显示在组件页面中。在此函数中,我们为 Add
、Edit
和 Delete
学生详细信息创建了单独的函数,并调用 Web API 的 Get
、Post
、Put
和 Delete
方法来执行 CRUD 操作,并在 HTML 中调用所有函数并绑定结果。
@code {
private CustomerMaster[] custs;
CustomerMaster custObj = new CustomerMaster();
string ids = "0";
bool showAddrow = false;
bool loadFailed;
protected override async Task OnInitializedAsync()
{
ids = "0";
custs = await Http.GetJsonAsync<CustomerMaster[]>
("/api/CustomerMasters/");
}
void AddNewCustomer()
{
ids = "0";
showAddrow = true;
custObj = new CustomerMaster();
}
// Add New Customer Details Method
protected async Task AddCustomer()
{
if (ids == "0")
{
await Http.SendJsonAsync
(HttpMethod.Post, "/api/CustomerMasters/", custObj);
custs = await Http.GetJsonAsync<CustomerMaster[]>
("/api/CustomerMasters/");
}
else
{
await Http.SendJsonAsync(HttpMethod.Put, "/api/CustomerMasters/" +
custObj.CustCd, custObj);
custs = await Http.GetJsonAsync<CustomerMaster[]>
("/api/CustomerMasters/");
}
showAddrow = false;
}
// Edit Method
protected async Task EditCustomer(string CustomerID)
{
showAddrow = true;
ids = "1";
//try
//{
loadFailed = false;
ids = CustomerID.ToString();
custObj = await Http.GetJsonAsync<CustomerMaster>
("/api/CustomerMasters/" + CustomerID);
string s = custObj.CustCd;
showAddrow = true;
// }
//catch (Exception ex)
//{
// loadFailed = true;
// Logger.LogWarning(ex, "Failed to load product {ProductId}", CustomerID);
//}
}
// Delte Method
protected async Task DeleteCustomer(string CustomerID)
{
showAddrow = false;
ids = CustomerID.ToString();
await Http.DeleteAsync("/api/CustomerMasters/" + CustomerID);
custs = await Http.GetJsonAsync<CustomerMaster[]>("/api/CustomerMasters/");
}
}
导航菜单
现在我们需要将这个新添加的 CustomerEntry
Razor 组件添加到我们的左侧导航。为此,打开 Shared 文件夹并打开 NavMenu.cshtml 页面并添加菜单。
<li class="nav-item px-3">
<NavLink class="nav-link"
href="CustomerEntry">
<span class="oi oi-list-rich"
aria-hidden="true"></span> Customer Master
</NavLink>
</li>
构建并运行应用程序
关注点
请注意,在创建 DBContext
并设置连接字符串时,不要忘记添加您的 SQL 连接字符串。在这里,我们已经在 SQL Server 中创建了表并与 Web API 一起使用。您也可以通过服务和 Code First 方法来完成。希望大家喜欢这篇文章。在下一篇文章中,我们将看到更多使用 Blazor 的示例。使用 Blazor 真的很酷很棒。
历史
- 2019 年 12 月 12 日:初始版本