ASP.NET Core MVC 前端组件快速使用总结
按钮跳转
1. 使用锚标签 (最简单)
html
<!-- 基础跳转 -->
<a href="/Home/Index" class="btn btn-primary">返回首页</a>
<!-- 使用 Razor 助手生成 URL -->
<a href="@Url.Action("Index", "Home")" class="btn btn-primary">返回首页</a>
<!-- 使用标签助手 (推荐) -->
<a asp-controller="Home" asp-action="Index" class="btn btn-primary">返回首页</a>
<!-- 带参数的跳转 -->
<a asp-controller="Product"
asp-action="Details"
asp-route-id="@Model.ProductId"
class="btn btn-info">查看详情</a>
使用表单提交按钮
html
<!-- 普通表单跳转 -->
<form method="get" action="@Url.Action("Search", "Product")">
<input type="text" name="keyword" />
<button type="submit" class="btn btn-primary">搜索</button>
</form>
<!-- 使用标签助手的表单 -->
<form asp-controller="Product" asp-action="Search" method="get">
<input type="text" name="keyword" />
<button type="submit" class="btn btn-primary">搜索</button>
</form>
使用 JavaScript 跳转
html
<!-- 直接跳转 -->
<button onclick="window.location.href='@Url.Action("Index", "Home")'"
class="btn btn-secondary">返回首页</button>
<!-- 带确认的跳转 -->
<button onclick="confirmRedirect()" class="btn btn-danger">删除</button>
<script>
function confirmRedirect() {
if (confirm('确定要删除吗?')) {
window.location.href = '@Url.Action("Delete", "Product")';
}
}
// 使用事件监听器 (推荐)
document.getElementById('myButton').addEventListener('click', function() {
window.location.href = '@Url.Action("Create", "Product")';
});
</script>
使用 Razor 的 ActionLink (传统方式)
csharp
@Html.ActionLink("返回首页", "Index", "Home", null, new { @class = "btn btn-primary" })
<!-- 带参数的 ActionLink -->
@Html.ActionLink("编辑", "Edit", "Product", new { id = Model.Id }, new { @class = "btn btn-warning" })
<!-- 带 HTML 属性的 -->
@Html.ActionLink("删除", "Delete", "Product",
new { id = Model.Id },
new { @class = "btn btn-danger", onclick = "return confirm('确定删除吗?');" })
常用表单组件
1. 表单构建
html
<!-- 使用标签助手 -->
<form asp-controller="Product" asp-action="Create" method="post" class="form-horizontal">
@Html.AntiForgeryToken() <!-- CSRF 防护 -->
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-success">保存</button>
</form>
2. 输入控件
html
<!-- 文本框 -->
<input asp-for="Email" class="form-control" placeholder="请输入邮箱" />
<!-- 密码框 -->
<input asp-for="Password" type="password" class="form-control" />
<!-- 隐藏域 -->
<input asp-for="Id" type="hidden" />
<!-- 文本域 -->
<textarea asp-for="Description" class="form-control" rows="4"></textarea>
<!-- 复选框 -->
<div class="form-check">
<input asp-for="IsActive" class="form-check-input" />
<label asp-for="IsActive" class="form-check-label">是否激活</label>
</div>
<!-- 单选按钮 -->
<div class="form-check">
<input asp-for="Gender" type="radio" value="Male" class="form-check-input" />
<label class="form-check-label">男</label>
</div>
3. 下拉列表
html
<!-- 基本下拉 -->
<select asp-for="CategoryId" asp-items="@Model.Categories" class="form-control">
<option value="">-- 请选择 --</option>
</select>
<!-- 多选下拉 -->
<select asp-for="SelectedTags" asp-items="@Model.Tags" class="form-control" multiple>
</select>
<!-- 不使用标签助手 -->
@Html.DropDownListFor(m => m.CategoryId,
new SelectList(Model.Categories, "Value", "Text"),
"-- 请选择 --",
new { @class = "form-control" })
数据展示组件
1. 表格展示
html
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach (var product in Model.Products)
{
<tr>
<td>@product.Id</td>
<td>@product.Name</td>
<td>@product.Price.ToString("C")</td>
<td>
<a asp-action="Edit" asp-route-id="@product.Id" class="btn btn-sm btn-primary">编辑</a>
<a asp-action="Details" asp-route-id="@product.Id" class="btn btn-sm btn-info">详情</a>
<a asp-action="Delete" asp-route-id="@product.Id" class="btn btn-sm btn-danger">删除</a>
</td>
</tr>
}
</tbody>
</table>
2. 分页组件
html
<!-- 手动分页 -->
<nav aria-label="Page navigation">
<ul class="pagination">
@if (Model.HasPreviousPage)
{
<li class="page-item">
<a class="page-link" asp-action="Index"
asp-route-pageNumber="@(Model.PageIndex - 1)">上一页</a>
</li>
}
@for (int i = 1; i <= Model.TotalPages; i++)
{
<li class="page-item @(i == Model.PageIndex ? "active" : "")">
<a class="page-link" asp-action="Index" asp-route-pageNumber="@i">@i</a>
</li>
}
@if (Model.HasNextPage)
{
<li class="page-item">
<a class="page-link" asp-action="Index"
asp-route-pageNumber="@(Model.PageIndex + 1)">下一页</a>
</li>
}
</ul>
</nav>
验证和提示
1. 客户端验证
html
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
<!-- 在表单中使用 -->
<form asp-action="Create">
<div class="form-group">
<label asp-for="Email"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</form>
2. 显示验证摘要
html
<!-- 显示所有错误 -->
<div asp-validation-summary="All" class="text-danger"></div>
<!-- 只显示模型级错误 -->
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
3. 临时消息 (TempData)
csharp
// 在 Controller 中设置
public IActionResult Create(Product product)
{
if (ModelState.IsValid)
{
// 保存逻辑
TempData["SuccessMessage"] = "产品创建成功!";
return RedirectToAction("Index");
}
return View(product);
}
html
<!-- 在视图中显示 -->
@if (TempData["SuccessMessage"] != null)
{
<div class="alert alert-success alert-dismissible fade show" role="alert">
@TempData["SuccessMessage"]
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
}
布局和部分视图
1. 布局页面 (_Layout.cshtml)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - 我的应用</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">我的应用</a>
<partial name="_LoginPartial" />
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© @DateTime.Now.Year - 我的应用
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
2. 部分视图
html
<!-- _ProductCard.cshtml -->
@model Product
<div class="card">
<div class="card-body">
<h5 class="card-title">@Model.Name</h5>
<p class="card-text">@Model.Description</p>
<p class="card-text">价格: @Model.Price.ToString("C")</p>
<a asp-action="Details" asp-route-id="@Model.Id" class="btn btn-primary">查看详情</a>
</div>
</div>
<!-- 在视图中使用 -->
<div class="row">
@foreach (var product in Model.Products)
{
<div class="col-md-4">
<partial name="_ProductCard" model="product" />
</div>
}
</div>
AJAX 请求示例
html
<button id="loadDataBtn" class="btn btn-primary">加载数据</button>
<div id="dataContainer"></div>
@section Scripts {
<script>
$(document).ready(function() {
$('#loadDataBtn').click(function() {
$.ajax({
url: '@Url.Action("GetData", "Product")',
type: 'GET',
data: { categoryId: 1 },
success: function(data) {
$('#dataContainer').html(data);
},
error: function() {
alert('加载失败');
}
});
});
// 使用 Fetch API (现代方式)
async function loadData() {
try {
const response = await fetch('@Url.Action("GetData", "Product")');
const data = await response.text();
document.getElementById('dataContainer').innerHTML = data;
} catch (error) {
console.error('Error:', error);
}
}
});
</script>
}
最佳实践建议
-
使用标签助手:优先使用标签助手(如 asp-action、asp-controller),它们提供编译时检查
-
Bootstrap 集成:充分利用 Bootstrap 的样式类
-
部分视图:将可重用的 UI 组件提取为部分视图
-
客户端验证:结合服务器端验证,提供即时反馈
-
响应式设计:确保组件在不同设备上正常显示
-
无障碍访问:为所有交互元素添加适当的 ARIA 属性